はじめに
こんにちは!
2024年4月の1ヶ月間、「CA Tech JOB」インターンシップに参加したnakaCです。
インターンシップで行ったことを振り返りつつ、学んだことや感想などを記事にします!
配属チームとプロダクト
AI Shiftの開発チームにバックエンドエンジニアとしてジョインしました。
AI Shiftは企業が抱える課題をAIを軸に解決していく事業を行っており、複数のSaaSプロダクトを保有しています。
私はその中でもAIコールセンター領域の生成AIを活用したオペレーターと顧客の会話を要約する「AI Messenger Summary」というプロダクトに携わりました。
行ったタスク
設計管理画面のファイルアップロード処理を、「設計 → 実装 → インフラ構築」という流れで行いました。
設計管理画面とは、会話要約するためのAIに対するプロンプトを思案・作成するための管理画面のことです。
この設計画面で、設計チームが音声ファイルを元に、適切なプロンプトの検証を行います。
ファイルアップロードの方法
今回のタスクのファイルアップロード処理には2つの方法がありました。
1つ目は一般的な、`multipart/form-data`等でクライアントサイドからサーバサイドにデータを渡し、ファイルをアップロードする方法です。
この方法は、シンプルな実装になるため軽いテキストファイルなどであればとても有効です。
ですが、音声ファイルや動画ファイルのような重たいファイルを扱う際にはサーバに負荷がかかってしまいます。
2つ目は署名付きURLを用いてクライアントサイドからファイルをアップロードする方法です。
署名付きURLとは、一定期間だけファイルストレージに対してアクセス権が付与されたURLのことです。
この署名付きURLを使用することでクライアントサイドからGCSに対してファイルをアップロードすることができます。
下記が署名付きURLを用いたクライアントサイドからのファイルアップロードの流れです。
サーバで認証を行い、署名付きURLを発行し、そのURLを元にクライアントサイドからGCSに対してファイルをアップロードします。
今回は音声ファイルという重たいリクエストが想定されていたため、サーバの負荷を減らせる署名付きURLを用いたファイルアップロード方法にしました。
設計
私がインターンシップに参加した段階では、ファイルアップロード処理以前に設計管理画面の仕様が定まっていない状態でした。
自分だけでは決められない部分が多かったので相談会を設けて、設計管理画面をどこに作成するか、どの画面から遷移させるか、認証方法はどうするかなどを決めていきました。
その後ファイルアップロード処理の設計を行いました。
- 新しくバケットを作成するか or 既存のバケットを使うか
- バケットは一つか or 複数に分けるか
- API設計
- ディレクトリの切り方やクリーンアーキテクチャに沿った実装方針
私は、設計は考慮漏れや実装の手戻りを減らすために行うものであり全ては自分のためだと考えていました。
しかしトレーナーの方に、他の観点から設計がなぜ大切かを教えていただきました。
「設計で他人を巻き込むことは大事。自分が関わっていないものはレビューコストが大きくレビューしづらいため、レビューする側としても予めなぜそのような実装にしたのか共有してもらえるとスムーズになる」
これまでのインターンシップでレビューを行ってこなかった自分には、そこまでの考えをもって設計に取り組めていませんでした。
設計は自分のためだけにやるのではなく、レビュワーのレビューコストを抑えることも考慮して他の方に共有しながら行おうと思いました。
実装
署名付きURL生成のコードはGCPのドキュメントにサンプルがあったため、そのコードを参考にクリーンアーキテクチャに沿って実装を行いました。
実装中、特に教えていただいたこととして 「技術的関心(GCS周り)はinfrastructure層にまとめる」ということです。
署名付きURLの生成ロジックはdomainモデルが存在せず、私はこれまでに、domainモデルやDBありきのレイヤードアーキテクチャしか実装してこなかったので最初は戸惑いました。
domain層の repository interface の命名を`GCSRepository`という名前にしてdomain層にGCSという技術的関心を混ぜてしまったり、usecase層で`bucket`を取得してしまい(azureではバケットのことをコンテナと言うなどバケットはAWSやGCPなど固有のものであり技術的関心に分離される)usecaseがインフラ側の実装を知っているようなコードになっていました。
上記の点をわかりやすく丁寧にレビューで指摘していただきとても勉強になりました。
保守性・可読性を考慮するために、上位レベルのdomain層やusecase層から技術的関心を排除して、下位レベルのinfrastructure層に詳細をまとめる大切さを学びました。
インフラ構築
実装が終わった後はTerraformを用いてインフラ構築を行いました。
Terraformとはコードベースでインフラを構築できるIaC(Infrastructure as Code)ツールです。
私はTerraform完全初心者だったので、キャッチアップのためにTerraformの公式ドキュメントを読み進めていました。
ですが、Terraformを勉強しているつもりがいつの間にかGCPの勉強になっていました。
正直Terraform自体はそこまで難しくなく、どちらかというとGCPのことをちゃんと理解していないが故の難しさがありました。
Terraformのドキュメントは読みやすかったですが、GCPのドキュメントは情報が散乱していて読みづらいかったです…
(って話をしたらAzureはもっとすごいぞ!とエンジニアの方に教えてもらいました。インフラエンジニア恐るべし)
インフラの知識不足を強く感じたので今後の課題として注力していこうと思いました。
TerraformやGCPのキャッチアップが終わった後、署名付きURLを生成するためのインフラのリソースと権限周りの調査を行いました。
リソース調査周りに関する詳しい内容は別途、技術記事を書かせていただきました。
フロントエンドから署名付きURLを使ってファイルアップロードする場合、サーバで CORS の設定をする必要がありましたが、オリジンやプリフライトリクエストなど初めて聞く単語ばかりでとても勉強になりました。
学び
タスクを通しての学び
設計・実装・インフラ構築と一気通貫で取り組むことができ、その過程で様々なことを学びました。
設計
- 仕様の決め方
- API設計
- 他人を巻き込むことの重要性
実装
- クリーンアーキテクチャ
- domainモデルが存在しない場合の実装方法
- 技術的関心分離の大切さ
インフラ構築
- Terraform
- GCP
- リソース調査方法
タスク以外の学び
SaaS初期は受託開発
インターンシップを通しての印象として、思った以上に受託開発感がありました。
求められてから(契約取れてから)本格的に開発した方が外れることは基本無いため、とてもいい戦略だと思いました。ですが、企業ごとにカスタマイズしていると事業のスケールが難しそうでした。
これまでは、完全なSaaSプロダクトのインターンシップにばかり参加してきたので、初期の事業戦略やスケールする前の開発を知れたことは非常に勉強になりました。
リファインメント・トリアージ
私が携わったプロダクトはリリース前でした。
やりたいことが大量にあってもリリースという締め切りがあるため、実装コストに見合うだけの価値が生まれるかどうかを判断しながら、工数調整や優先順位付けをしていく様子はとても学びになりました。
出社・ランチ
私は元々リモート派でしたが、インターンシップを通して対面による質問のしやすさやコミュニケーションの取りやすさを知り、対面も悪くないと思うようになりました。
出社時には社員さんとランチをすることができ楽しかったです!
新卒就活時に何を考えていたか、今後のキャリア論についてなど様々な話を聞くことができ勉強になりました。
おわりに
今回のインターンシップでは、設計からインフラ構築まで開発の一連の流れを経験させていただき、とても成長することができました!
タスクが無事完了できたのも、トレーナーの加々美さんを始め、メンターの木村さん、フロントエンドの栗崎さん、テックリードの由利さん、開発チームの方々のサポートのおかげです!
本当にありがとうございました!!