大学生がGoとNext.js13で新世代AIタイピングゲームを作りました

# はじめに
こんにちは，記事を読んでくださりありがとうございます！
今回は開発経験ゼロだった自分が，GoとNext.jsとChatGPTのAPIを利用したタイピングゲームを作ったので紹介します！

### 簡単な自己紹介
自分は4カ月ほど前にJavaScriptの基礎のところから独学で勉強を始めた駆け出し大学3年生です．Next.jsやGoを中心にweb開発の勉強しています．そんな自分が勉強のアウトプットとして初めて作ったアプリを以前紹介したのですが，それを大幅に改善して作り直したので今回改めて記事にしました．
自分は経験が浅いのでなにか間違いや改善点があるかもしれませんが，もしあれば教えていただけると幸いです！

# アプリの概要
今回作った**AI Typing**はユーザが入力したテーマに応じてChatGPTがテキストを生成して，そのテキストでタイピングゲームができるアプリとなっています．

こちらが今回作成したアプリです↓↓(PCのみ対応してます)

https://ai-typing.app

GitHub リポジトリ↓↓

https://github.com/y4asse/ai-typing-front

https://github.com/y4asse/ai-typing-api



↓実際のプレイ画面
<img  width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3162990/3a466972-2810-66ca-2c96-111cb545ee6c.png">　<img width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3162990/280f40b0-a8d8-748f-cd16-f71b1a7a0cf3.png">

# アプリを作ったきっかけ
従来のタイピングゲームの問題点として<strong>
・決まった文章でしか遊べない
・文章が面白くない
・ユーザが文章の内容を選べない
</strong>があると考えました．

そこでユーザがお題を自由に指定して，それをもとにAIが生成した文章で遊ぶことができれば，とても面白くなるんじゃないかなと思ってこのアプリを作りました．

# アプリの機能
主要な機能
<strong>・テーマを指定して文を生成
・タイプ速度や正確率で計算されるスコア
・スコアランキング
・アカウント認証
・ゲーム履歴
・みんなの作ったテキストを見れる
・いいね
・バッチ制度(9/23追加)
・AI分析(8/12追加)
</strong>

その他
<strong>・ページネーション
・複数のローマ字入力方法に対応(「ちゃ」-> tya, cha)
・バリデーション
・twitterシェア機能(7/10追加)
・AIモデル選択(8/12追加)
</strong>

# 使用した技術
アーキテクチャに関して，一番気を使った点は<strong>スケーラビリティ</strong>です．今後アプリが大きくなった時(まだ分かりませんが笑)を考えたとき，密結合なアーキテクチャだと拡張や保守が大変だと思ったので，まずバックエンドとフロントエンドを切り離し，RESTでデータをやりとりをするようにしました．
アーキテクチャ図↓
<img width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3162990/576afa9c-2540-1d86-1cdb-4e367f1a8210.png">

## フロント
サクサク動くアプリを作りたかったので，フロントにはNext.js(react, typescript)を用いて実装しました．Next.jsを使うことで，**ルーティング**や**SSR**が簡単にできてバージョン13からサーバコンポーネントにも対応したので，**コンポーネント単位でSSRができる**のがとても便利だと感じました！

## バックエンド
バックエンドにGo(echo)を採用した理由としては，<strong>情報量の多さ</strong>と<strong>みんな同じような書き方になる</strong>という点がとても大きいです．僕は独学で勉強しているので，ネットの情報が少なかったり，いろんな書き方がある言語だと，詰まった時しんどいと思い最近多く利用されていて情報量の多いGoを選びました．

アーキテクチャは**クリーンアーキテクチャ**で実装しました．
<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3162990/5ad0d8a1-dc50-2f78-a41a-20e3ea1b55d7.jpeg">
疎結合な設計となっているので，もしアプリが大きくなっていったとき保守，運用がしやすいかなと思いました．

また**環境構築やデプロイを楽に**行えるようにdockerを利用しました．

## 認証
認証にはFirebase authとNextAuthを使用しました．はじめはFirebase authのみで実装でしようと思っていましたが，**ちらつきを無くしたかった**ので，サーバ側でもセッションを保持できるようにNextAuthを追加しました．

## デプロイ
フロントはVercelを採用しました．自動でビルド＆デプロイをやってくれて，Next.jsとの相性も良く，キャッシュとかも色々やってくれるのでVercelを選びました．

バックエンドにCloud runを採用した理由としては，**クラウドを触ってみたかった**というのが大きいです．自分はまだ経験が浅いので，フロントバックインフラ色々挑戦してみよう！と思っていたので，今回クラウドでGCPを使ってコンテナをそのまま乗っけるだけのCloud runを選びました．それに付随して，データベースはCloud SQLでPostgresを使用しました．

# CI/CD 
CI/CDはGithub Actionsでmainブランチにpushしたらデプロイしてくれるようにしました．以下の記事を参考にさせていただきました．

https://qiita.com/takengineer1216/items/cbbf95f9789996811575

## API
主役のChatGPTのAPIに加えて，Yahoo Japan!のAPIを使わせてもらいました．**AIが作った文章をどのようにローマ字に変換していくか**色々試行錯誤をして失敗を重ねる中，このAPIを知ってフリガナを振ってもらうことにしました．
↓Yahoo! JAPAN Webサービス

https://developer.yahoo.co.jp/sitemap/

# こだわった点
AIが文を作るという点だけでなく，タイピングゲームそのものにもこだわりました．その中で**ローマ字の複数の入力方法に対応す**るのがとても大変で，ここに1番時間を使いました．reactでの実装方法が分からず1週間くらい迷走してたと思います．「きゅうきゅうしゃ」を入力するだけで何十通りもあることを知りました...

↓実装するにあたって以下の記事を参考にさせていただきました．ありがとうございました！

https://qiita.com/Arthur_Lugh/items/43b61877819e402c50d6

# 追加したい機能・改善点
・時間制限の中でどれだけの文字を打てたかを競うモード
・いいね機能・いいねランキング
・他の人が作ったテキストで遊べる

・フォルダやファイルがごちゃごちゃになってしまったので，ベストプラクティスを学びたい
・クラウドについて，とりあえず動いてる状態だけど理解をもっと深めたい
・クラウドのコストが高すぎるので何とか抑えたい...

# 学んだこと
<strong>・Goを利用したAPIの実装方法
・セッションについての理解が深まった
・SSRやサーバコンポーネントについて理解が深まった
・クラウドがなんとなく分かった
</strong>

# フィードバック・お問い合わせ
ご意見，感想，改善点，バグ，質問などなんでも大丈夫です！
なにかあれば以下のフォームかtwitterまで気軽に送ってください！

https://forms.gle/aahaG8p9XByN7Vcs5

twitter↓
`https://twitter.com/y4isse`

# さいごに
ここまで記事を読んでくださりありがとうございます！
もっといろいろ書きたかったのですが，長すぎる記事になりそうだったのでここまでにしときます．今回の開発では，色々新しい技術に挑戦したり，失敗したりしてそこから多くの学びを得ることができたのでとてもいい経験になりました．これからももっといろいろ挑戦してワクワクできるようなアプリを作りたいです！

# 追記
7/10　フィードバックにてtwitterのシェア機能があればいいというお声をいただいたので，追加しました．ご意見ありがとうございます！