はじめに

こんにちは、COMSBIのエンジニアをやっているみなとです。
今回はCOMSBIでのアプリケーション開発を事例を交えて紹介します。

COMSBIの開発では主に開発手法としてDDD(ドメイン駆動開発)を用いています。 アーキテクチャはオニオンアーキテクチャをベースにCOMSBI用にチューニングしながら開発を進めています。 和田卓人氏の「質とスピード」に感銘を受け、その観点から前述した開発手法・アーキテクチャを用いるようになりました。

※注意点: 本記事(2023年7月時点)で紹介するCOMSBIのアプリケーション開発では「DDD」「オニオンアーキテクチャ」の個人的な解釈を交えていますので、もちろん「絶対正解」ではなく「一つの考え方」として紹介します。
厳密には違ってくる部分や妥協してる部分もありますが、みんなで議論してより良い開発を行ってきたいと思ってます。

弊社のプロダクトであるCOMSBIについての詳細は、COMSBIのサイトをご覧ください。

前提

  • COMSBIで作ってるAPIの一例
  • 実行環境はAWS Lambda
  • 実装はTypeScript
  • routingとかはexpress

フォルダ構成

基本domain、infrastructure、presentation、usecasesの4つは変わらず中のフォルダは結構案件による部分はある。
例えば、汎用的なロジックとかはusecasesの中にserviceとか作って入れたり
domainの中にerrorとかresponseとかのフォルダがあったりする

一連の流れ

  1. controllerでrequestを受け取る
  2. controllerでusecaseを呼び出す
  3. usecaseでrepositoryを呼び出す
  4. repositoryで外部とやりとりする
  5. usecaseでresponseを作る
  6. controllerでresponseを返す

Controller

1. controllerでrequestを受け取る 2. controllerでusecaseを呼び出す 6. controllerでresponseを返す

controllerでusecaseを呼び出す以外のことは基本的にやらない if分岐とかが入ってきたらおかしいと思って考え直して欲しい

usecase

3. usecaseでrepositoryを呼び出す 5. usecaseでresponseを作る

ロジックは全部usecaseで賄えばいいと思ってるが、そうするとusecaseが肥大化する気がする。 でもusecaseが肥大化するのは1APIの中でやることが多すぎるということなので、設計を見直すきっかけにもなると思うから問題ないかな。….多分

repository

4. repositoryで外部とやりとりする

repositoryの役割としては外部データ等をentityに詰め替えることだと思ってる。 でもって、repositoryをinterface作るようになってるのは、外部データの取得方法が変わった時にinterfaceを実装したクラスを変えるだけでいいようにするため。 usecaseで使う時に接続先がDBなのかredisなのかとかを気にしなくていいようにするため。 controllerでnew してるからそこで判断するとif分岐入るじゃんとかなるから、その時はfactoryみたいなの作ればいいかなと。
以上が簡単な一連の流れになると思う。

まとめ

  • controllerはrequestを受け取ってusecase呼び出してresponseを返すだけ
  • ロジックは全部usecaseでやる
  • repositoryは外部データをentityに詰め替えるだけ
  • repositoryはinterfaceを作っておく
  • 案件規模等によって妥協するとかは全然あり(ただ案件内で統一は必要)

ソニックムーブは一緒に働くメンバーを募集しています

Wantedlyには具体的な業務内容のほかメンバーインタビューも掲載しております。ぜひご覧ください。

あわせて読みたい記事