この記事は個人ブログと同じ内容です
こんにちは、株式会社ROXX で back check とうサービスを開発しているぐっきーです。 今回は back check で新しく toC 向けのプロダクトを新規リポジトリとして構築したので、その概要を紹介します。 なおこの記事では新規コードベースの立ち上げ、アーキテクチャについて説明しますが、サービスリリース自体はまだであるため、あくまで現状の進捗共有ということで解説していきす。
アーキテクチャの選択と背景
マイクロサービス
モノリスのコードベースで運用していたときの問題点として、既存のコードベースに負債もありつつ、プロセスの中でボトルネックとして話題に上がっていた問題として同じコードベースを複数チームで開発することに対するチーム間のコミュニケーションコストがありました。 これらを考慮して新規のプロダクトを立ち上げるタイミングで、責務の違う領域として新しくリポジトリを立てることとしました。 また開発者目線でも新しい技術やアーキテクチャを取り入れる機会ということで興味があったので純粋な興味という部分もありました。実際に現時点でできあがったプロダクトではメンバーの得意な技術やレイヤーを整理したアーキテクチャを取り入れたことで総合的に開発者体験は上がったと感じています。
技術スタック
- BFF - Backend for Frontend
- GraphQL
- TypeScript
- inversify - DI Container
- Next.js
- DynamoDB
- AWS Lambda
- Storybook
技術選定
DynamoDB
DynamoDB を採用した意図としては、主に以下になります。 - RDS の料金と比較してデータの読み書きの量に応じた価格設定のため、 back check のサービスの性質上、大量アクセスを捌くようなビジネスドメインではないため値段が安く抑えられる。 - RDS だと MySQL のバージョンアップなどに伴うダウンタイムやメンテナンスコストが発生するが Dynamo DB ではそれが不要になる。 - Dynamo DB で Single Table Design を採用すると join によるテーブルを跨いだデータアクセスが不要になり早いらしい。
そもそものきっかけとしては Tech Lead が Dynamo DB の採用を提案してくれましたが、チーム自体に知見はない状態だったので不安はありました。しかし back check の開発組織としてもキャッチアップにコストをかけることが許容してもらっていたため学習を前提としつつも採用することができました。
BFF
プロダクト自体が toC 向けということもあり、 back check 上で行うリファレンスチェックの候補者、推薦者フローを今後移植してくることを想定していたため、認証サービスを共通で使えるようにするということを一番の目的として BFF を採用しました。 また front と bff 間の通信を GraphQL を採用し、スキーマから型生成させることで型安全にアクセスできるようにしました。
Lambda
BFF, 各種 backend はそれぞれ個別のサービスとして lambda 上で動かしています。
Lambda で動かすことで各サービスの実行環境の運用をマネージドサービスに委譲しつつ、Dynamo DB ストリームによるイベント処理や、SQS, SNS を使ったキューイング、メッセージングをフックに連鎖的に処理を実行させることでサービス間の連携を行っています。
共通の DI コンテナ
各サービスの初期化時に DI コンテナを一通り初期化させ読み込むような実装となっています。 サービス毎に実行環境は分かれつつ、モジュラーモノリスのようにモノリポ全体のレイヤーを domain, repository(DynamoDB, backcheck_api など個別に用意している) とまとめて?管理しており、それぞれの bind を共通の DI コンテナを使って行っているため、全体の構造把握がしやすいのがメリットです。
※ ちなみにコードベース内のレイヤーの設計は厳密に DDD を採用しているわけではありません。どちらかというと DDD の設計パターンを参考にしているといった温度感で設計しています。
また全体的に抽象(インターフェース)に依存させる設計となっているため、依存関係逆転の法則でよく言われるテストのしやすさや、再利用性の向上もありつつ、テスト駆動開発のようにスコープを絞った開発ができることから、小さいスコープで着実に開発できることも嬉しいポイントです。
Dynamo DB の設計
Dynamo DB の特性を活かせるようにという意図で、Single Table Design を採用しました。 Single Table Design では join を使ってリレーションを表現するようなことができないため、設計方法のキャッチアップに苦労しました。
私たちがとった設計の流れとしては、まず RDS のように ER 図を起こしやりたいことを可視化し、そこから管理したい各データへのアクセスパターンを洗い出します。アクセスパターンを元にどのデータをまとめて持たせるとよいかを設計し、Table の Entity を起こしていくといった方法で進めていきました。
このとき RDB の考え方と大きく違う部分として、Single Table Design では参照したいデータをマスターデータからコピーして Entity の Item に格納するように設計します。こうすることによって、アクセスパターン毎に join してテーブルを跨いだデータアクセスをする必要がなく、データ取得までの速度が速くなります。
実際に設計してみた所感として、設計の考え方の違いからとっつきづらさはあったものの、気軽に参照用のデータを捨てられる点など RDB の基本的な設計では得られないメリットにより、変更がしやすくなったように思います。
※ Dynamo DB の設計について詳しく知りたい方は「The DynamoDB Book」という書籍が実例を添えて詳しく説明してくれているのでおすすめです。
サービス間連携
データ連係の部分は SQS を用いたキューイングをトリガーに Lambda を起動し、 backcheck_api で内部的に公開しているエンドポイントに直接 fetch する方法で実装しています。(今回のケースでは backcheck_api でマスターとなるデータを持っており、新プロダクト側で複製したデータを保存し、加工して View で表示させています)
サービスが独立して稼働できるように担保するための設計を意識しましたが、データ連携周りは DeadLetterQueue から復帰させるケースを考慮したりと単体のアプリケーション内では考える機会の少なかった部分まで考慮する必要があり、設計に苦労しました。
また、チーム間のデータ連携が必要な部分に関して、大きな部分は backcheck_api 側を管理するチームのリーダーと弊チームのリーダーで調整を行ってもらうことで解決しました。背景として、 backcheck_api 側の実装タスクを起こして依頼するフローとしていたのですが、オーバーオールリファインメントの場などでチケットの説明が必要であり、この場に毎回出席してくれているチームリーダーに調整役となってもらうこととしました。
チーム間の連携が必要な部分に関してはこれからもでてくると思いますが、今後の展開として調整作業のバス係数が2人以上になるような属人化を省く仕組みを考えていけたらいいなと個人的には思っています。
テスト設計
テスト設計についてはそれぞれユニットテストで担保しつつ、まだアプリケーション全体を通したテスト設計までは詰められておりません。 現状はユニットテストで補えない箇所は手作業による統合テストとモンキーテストによって行っています。 今後各サービス間の連携部分の結合を網羅するテストを全部手動で運用していくことはつらいため、この辺は E2E テストを採用する話が上がっている状況であり、技術選定中です。
front については Jest と testing-library/react を用いて各 Hooks と UI などのテストを実装しています。 また UI が定まってきたら Chromatic によるビジュアルリグレッションテストを導入予定です。
ログ戦略
ロギングの詳細な設計についてはまだ追いついていない状況です。 現状はサービス間の受け渡しなど、処理のつなぎ目となるところでログを仕込んでおり、datadog に流して管理しています。
余談ですが、AWS の XRay によって、処理がどこまで到達したか。各セクションでどの程度実行速度が掛かったか。が可視化されているため非常に便利です。
おわりに
さて、以上が大まかな back check の toC 向けプロダクトの概要説明でした。まだまだ一般公開しておらず、よく言われるマイクロサービスの運用においてのつらみについてはまだ充分に学習できていませんが、今後も柔軟に対応しつつ開発組織として知見を溜めてどんどん展開していけたらと思っております。 また、今回の内容に含められなかった部分についても今後どしどし紹介していきたいと思います。 最期になりますが、back check ではモダンなアーキテクチャや、組織開発、HR Tech 領域に興味のある方を絶賛募集しております。もし上記の内容にご興味を持っていただけたら、お気軽にカジュアル面談ご依頼ください。
back check のカジュアル面談の窓口が見つからなかったのでお隣の agent bank 事業部の求人を貼っておきますw
また個人的に話を聞いてみたいなども大歓迎ですので、お気軽に DM いただければと思います。