レイヤードアーキテクチャは、コードを責務ごとの層に分け、上位層から下位層へ処理を委ねる基本構成です。

4つの層
| 層 | 主な責務 | 置かないもの |
|---|---|---|
| Presentation | HTTP、画面、入力形式の変換 | 業務ルール、SQL |
| Application | ユースケースの手順 | HTTP表現、DB詳細 |
| Domain | 業務ルールと状態 | UI、ORM設定 |
| Infrastructure | DB、外部API、ファイル | 画面制御 |
注文確定APIなら、処理は次のように進みます。
Controller
→ ConfirmOrderService
→ Orderの業務ルール
→ Repository / DB
返却時は逆方向に値が戻ります。実行時の呼び出し順とソースコードの依存方向は同じとは限りません。Repository interfaceを内側に置き、Infrastructureが実装する構成では、実行時は内側からDB実装を呼んでも、コード依存は外側から内側へ向けられます。
層ごとの判断
Controllerは、入力検証、認証情報の受け渡し、HTTPレスポンスへの変換を担当します。注文可能かどうかまで判断すると太りすぎです。
Application Serviceは、取得、Domain操作、保存というユースケースを調整します。あらゆる処理をUserServiceのような1クラスへ集めると、変更理由が混ざります。操作単位に分けます。
Domainには、状態によって許される操作や計算を置きます。単純なCRUDで守るルールがないなら、無理に複雑なDomain Modelを作る必要はありません。
InfrastructureはSQLや外部SDKを扱います。ORM EntityやQuery BuilderをPresentationまで返すと、層を越えてDBの都合が漏れます。
ショートカットの扱い
「必ず隣の層だけを呼ぶ」厳格なレイヤーと、上位層から下位層を直接呼べる緩いレイヤーがあります。どちらを選ぶかは規模と変更頻度で決めます。
たとえば参照だけの単純な画面で、Applicationから専用Queryを使うことはあります。ただし、例外を無秩序に増やすと責務が崩れます。許可する依存をチームで明文化します。
まとめ
- 層はPresentation、Application、Domain、Infrastructureなどに分ける
- 上位層は手順を委ね、下位層は自分の責務だけを扱う
- 実行時の呼び出しと、コードの依存方向を区別する
- Controller、Service、ORMを層の外へ漏らさない
- 小さなCRUDでは必要な層だけから始める
Domain中心の依存方向はオニオンアーキテクチャ、外部接点の交換はヘキサゴナルアーキテクチャを参照してください。