クリーンアーキテクチャを実際にAPI設計に適用する場合の構成を考えたのでまとめ。
クリーンアーキテクチャ構成要素
- 依存関係は常に一方向
エンティティ
- コアロジックを記述
- 多くの場合データモデルが記述される。
- DBにデータを保存する場合、インターフェースの注入を行う。
ユースケース
- アプリケーション固有のルールを構築する
- シーケンスを記述。ロジック依存の制御構文はユースケースに記述される
インターフェースアダプター
- 外部との接続。入力を受付てユースケース関数に流す
- APIHandler、 DBManagerなど
フレームワーク&ドライバ
- Router
- EntryPoint
参考:https://qiita.com/hirotakan/items/698c1f5773a3cca6193e
goでAPIを書く場合のソースコード構成
- src
- entity
- ロジックを書く。
- usecaseから受け取ったInterfaceを実行して処理する。
- usecase
- APIHandlerからRequest、Repostiry、Interfaceを受け取ってentityを呼び出す
- シーケンスを記述する。シーケンスだけを書く
- 使うInterFaceはユースケースに記載
- Interface
- APIInterface
- 外部APIの呼び出し処理を記述
- Repositry
- データストアが持つデータを記述。
- APIHandler
- エンドポイントを書く
- APIの入力とResponseを整理する
- Driverを受け取って、usecaseを呼び出す
- usecase が利用するRepositoryとAPIInterfaceをここで設定
- 各InterFaceを紐づけする
- APIInterface
- driver
- router.go
- ルーティングを記述
- 使うその他driverをすべてここで渡す
- datastore.go
- Datastoreのライブラリを記述
- ここのインフラは別に何でも良い
- redisやdbなどのアクセサー
- 必要ならこの辺にかいておく
- redisやdbなどのアクセサー
- router.go
- main.go
- driverを呼び出す。
- entity
メリット
- 依存関係は常に一方向となるのでテストを書きやすい
- DBやインフラ、API等のテストモジュールは使いまわしが効くので一度書けばテストが簡単
- DB等の機能と直接関わらないインフラ差替が比較的容易
- GCPに乗せるからDatastoreを使おう、とか検証用に一旦sql使っとこう、みたいな差替が楽
デメリット
- 依存性を一方向にするために依存性の注入をしているため、適当にかくと逆に読みづらいコードが出来上がる
- 依存性の注入を行うインターフェースはデータインフラや外部API発行等になるので、利用するインターフェースを予めルール化しておけば解決するとはおもう
- ルーティングとシンプルなロジックで処理できる規模のAPIしか作らないなら冗長