話題のOpenAIを使った資格対策アプリを開発した話 with サーバレスアーキテクチャ

# まずどんなアプリか
ブラウザで動作するSPAアプリケーションです。

IELTSという英語の試験の4技能あるのうちのライティングの学習を
効率化するためのアプリです。
ライティング試験はエッセイを2種類書くタイプですので、
アプリの機能としては問題を登録し、
問題に対してエッセイを作成、保存、レビューができるのがメインとなります。
レビューは今話題のOpen AIのAPIを使用しています。
ロジックとしては基本的なCRUDに毛が生えた難易度です。

# アプリのサイト情報、ソースコード
実際のアプリはこちら
https://www.ielts-writing-helper.com/


https://youtu.be/pw9w-9cQE6g



バックエンド
https://github.com/KoeInoue/writing-backend
フロントエンド
https://github.com/KoeInoue/writing-frontend

LPはリポジトリを分けていますが現在は公開していません。


# アーキテクチャ全体像
![Diagram](https://storage.googleapis.com/zenn-user-upload/625937049153-20230321.jpg)

フロントエンドのホスティングはAmplify、
バックエンドはAWS SAMで
LPはバンドルサイズを最小にしてレスを最速にするため
アプリごと切り離してVercelにデプロイしています。

# 技術の採用理由&感想

## AWS SAM
**採用理由**
[serverlessフレームワーク](https://www.serverless.com/)という選択肢も
ありましたが、GUIのDynamoDB Adminにバグが出ていて使えなかったのでSAMにしました。
今回に至ってはどちらでもいいような気がします。

**感想**
AWS公式のツールということで、とくに不自由なく開発できました。
良かった点としてはビルドやデプロイもコマンド一発でできますし
ローカル開発にも対応していますが、
Dynamodbは別途Dockerイメージを用意する必要がありました。

### API Gateway & Lambda
**採用理由**
Goを書きたい！という優先度高めの欲求があったので
GoをサポートしているLambdaを採用しました。
料金は従量課金であり、EC2やECSに比べて安価になるはずです。
また、スケーリングや可用性についても全く心配ありません。

**感想**
リリースまでステージング上で使いまくってましたが0円でした。
ECSの場合個人にしては結構な打撃かと思います。笑
レスポンス速度は問題なく、デプロイに関してもSAMがWrappingしてくれて
いるため非常に楽です。


### Dynamodb
**採用理由**
RDSなどのRDBMSを採用してしまうと月額1000円以上かかってくるため
なるべく避けたかったというのとLambdaとシナジーがあるため採用しました。

**感想**
ホントはRDSを使いたかった...
Dynamodbの概念の理解に苦しみ、なかなか設計が進まずでした。
設計の流れとしてはこちらを参考にさせていただきました🙇🏻‍♂️
https://qiita.com/_kensh/items/2351096e6c3bf431ff6f

なんとか設計できたものの、GoのLambdaから操作するにしてもORMのような
ライブラリがないためAWS SDKを使ってコードをガリガリ書かなければならないため
しんどかったです。。。
将来RDBに載せ替えることを想定し、
しっかりRepository層を抽象化しておきました。笑
ただお財布には非常に優しいです。

## GraphQL
**採用理由**
GraphQLはAPIを柔軟かつ効率的に設計でき、
前後端の開発者のコミュニケーションを改善するため、
スムーズな開発プロセスを実現できるためです。
また、データの取得や更新に必要な情報を明確に定義でき、
ネットワークトラフィックやサーバー負荷を削減することができます。

**感想**
チーム開発の場合はスキーマを公開することでコミュニケーションを
円滑に取ることができそうだなあと思いました。(今回は一人でしたが...)
オーバフェッチをなくせるので
ネットワークトラフィックやサーバー負荷の削減にもなったはず。

### gqlgen
**採用理由**
gqlgenはGo言語でGraphQLサーバーを開発するのに
必要な機能を提供するライブラリです。
スキーマ駆動で開発を進められる点に惹かれました。
graphqlファイルにスキーマを書いて
コマンド一発でリゾルバーとモデルを生成できるすぐれものです。
実行速度も比較的早いらしく、Graphqlの弱点といえる
N+1問題のソリューションもしっかり備わっています。
Playground(GUI)でクエリを実行できるページもあり、チーム開発にも適しています。

**感想**
リゾルバーとモデル自動生成でスムーズに開発できました。


## AWS Amplify
**採用理由**
ホスティングに関してはVercelと迷いましたが、
バックエンドとしてストレージや認証を提供しているため
Amplifyにしました。
ホスティングに関してもVercelに勝っている点として
ベーシック認証が簡単という点があります。
ただ、デプロイした分だけ課金されるので注意が必要です。

**感想**
Githubのリポジトリと連携してデプロイできるため
非常に簡単でした。
ストレージや認証機能も非常に便利です。
CLIでポチポチやっているとバケットとCognitのプールを作ってくれます。笑
認証に至ってはログイン画面のUIも提供されているのには驚きでした…


## React ~~Next.js~~
**採用理由**
今話題のSSRを使ってみたい！ということでNext.jsに
しましたがAmplifyでのページ描画が遅すぎるとの
確率でページがレンダリングされないバグが有り、残念でした。
エラーログは出ておらず、解決を断念しReactにReplaceしました。

**感想**
そもそもこの手のアプリはSSRじゃないほうが体験がいい。

## Redux
**採用理由**
難しいという固定観念がありましたが
一番人気なので学んでおいて損はないということで採用。

**感想**
そこまで難しくなく、簡単に操作できるライブラリが提供されていました。


# 新たな機能の追加と改善
## 文法チェック機能
**追加理由**
エッセイ作成において、文法の正確さも重要です。そのため、ライティングの品質を向上させるために、文法チェック機能を追加しました。この機能により、ユーザーは自分のエッセイに対して自動的に文法チェックを行い、指摘された箇所を修正することができます。

**技術的な実装**
文法チェック機能を実現するために、外部のAPIを利用しました。Grammarly APIが利用可能です。APIを利用することで、簡単にエッセイの文法チェックが行えるようになりました。
公式でReact SDKが提供されています。
https://developer.grammarly.com/docs/editor-sdk-react


## エッセイAI自動評価機能
**追加理由**
ユーザーが自分のエッセイに対して客観的な評価を得ることができるように、エッセイ自動評価機能を追加しました。この機能により、ユーザーは自分のライティングスキルを把握し、改善に役立てることができます。

**技術的な実装**
エッセイ自動評価のために、機械学習モデルを活用しました。Open AI などの事前学習済みモデルを利用して、エッセイの自動評価が可能です。人工知能APIを AWS Lambda からコールし、レスポンスをDBに保存しています。
Open AIのCompletionを使用しました。
https://platform.openai.com/docs/api-reference/completions

## ユーザーフレンドリーなUI/UXの改善
**改善理由**
アプリの利用者がストレスなくエッセイの作成やレビューができるように、UI/UXを改善しました。アプリの使いやすさは、ユーザー継続率や満足度に大きく影響するため、この点は重要です。

**技術的な実装**
Reactを利用して、コンポーネントベースのUI設計を行いました。また、UIライブラリである Material-UI や Ant Design を使用して、一貫性のあるデザインと使いやすさを実現しました。モバイルファーストなデザインを採用し、スマートフォンやタブレットでも快適に使用できるようにしました。


# まとめ

本記事では、個人開発でAWS SAMとAmplifyを採用した
サーバレスアーキテクチャを構築する理由と感想について述べました。
AWS SAMやAmplifyを利用することで、開
発効率の向上やコスト削減、スケーラビリティの確保などが実現できました。
また、技術スタックとしてGraphQL, Go, React, Reduxなどを活用し
、効率的な開発を行いアプリの使いやすさや品質も向上させることができました。

これらの技術選定や経験は、今後の個人開発やチーム開発においても
有益な知見となることでしょう。個人開発者にとって、
自分に合った技術スタックを見つけることは非常に重要です。
自分のニーズや予算に応じて、柔軟に技術選定を行うことで、
より効果的な開発が可能になります。今後も新しい技術や手法を取り入れながら、
アプリの改善と発展を目指してまいります。