- Published on
アプリのDIR構成とクリーンアーキテクチャなど
- Authors
- Name
- Kikusan
フロントエンド・バックエンド分離構成のときのDIR構成の悩みポイントを記載。
アーキテクチャについて
レイヤードアーキテクチャ
技術的な関心ごとの切り口。 以下の流れで上から下に依存関係を構築する。(層の名前はアプリごとにn個あって良い) モノリシックなデプロイメントの性質を持つ。
- presentation層:ユーザインタフェースをバックエンドとの通信ロジックに責任がある
- application層:ユースケース毎にドメインオブジェクトの操作を行う
- domain層:ドメイン毎にビジネスロジックを実装する。
- infrastructure層:データベースや外部と接続
クリーンアーキテクチャ
技術的な関心ごとの切り口。 レイヤードでDBを移行すると依存関係があるためdomainも書き換えないといけないといった問題を解消する。 コアの外側から内側に依存する。 https://zenn.dev/sre_holdings/articles/a57f088e9ca07d#%E7%BD%AE%E3%81%8D%E6%8F%9B%E3%81%88%E3%82%8B
マイクロサービスアーキテクチャ
業務的な関心ごとの切り口。 ドメインごとに分割してアプリを構築しそれぞれがDBを持つ。アプリ間は通信リンクする。
分散しているため可用性が高まる。が適切な分割粒度が難しい。通信は性能にもろ影響する。
サービス間の全ての通信を管理するソフトウェアレイヤをサービスメッシュという。o11y向上やトラフィック管理ができる。
モジュラーモノリス
業務的な関心ごとの切り口。 モジュラーモノリスではアプリ内のモジュールを分割することで業務ドメインを分離する。 モノリスより疎結合であるため、開発効率向上が見込める。 マイクロサービスより遅延がなく、トランザクション管理も用意。
バックエンドのDIR構成
バックエンドはドメインは処理が混ざり合うことが多いので、
基本的にはクリーンアーキテクチャを採用しておけば問題ないだろう。
その上で業務的な関心ごとでサブ分離しておけば、いざマイクロサービスにしたいとなっても移行が楽になりそう。
src/
├── domain/ # エンティティ、リポジトリインターフェース、ユースケース
├── application/ # ユースケース実装
├── infrastructure/ # DBや外部APIとのやりとり
├── presentation/ # コントローラー、ルーティング
├── config/ # 設定
フロントエンドのDIR構成
業務型だとこんな感じ。(nextの場合)
src/
├── features/
│ ├── tasks/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── types/
│ │ └── api/
│ └── users/
│ ├── components/
│ └── ...
├── shared/
│ ├── components/
│ ├── hooks/
│ ├── utils/
│ └── types/
├── app/
└── lib/
デザイン型であればこんな感じ(AtomicDesignで分割)。
src/
├── components/
│ ├── atoms/
│ ├── molecules/
│ ├── organisms/
│ ├── templates/
│ └── pages/
├── hooks/
├── utils/
├── types/
└── api/
レイヤ型であればこんな感じ。
src/
├── presentation/ # UIコンポーネント、ページ
├── domain/ # ビジネスロジック、エンティティ、ユースケース
├── infrastructure/ # APIクライアント、外部サービス
├── shared/ # 共通ロジック
└── app/ # ルーティングやエントリポイント
いい感じに混ぜ合わせてみる。
業務型だとsharedに入れるか悩みそう。 デザイン型だとコンポーネント分割した後の業務的な関心毎に分割するのが難しい。
レイヤ型はUIとビジネスロジックが分離するから、コンポーネントに書く処理に迷う。
src/
├── app # ルーティングやエントリポイント page, templateのデザインを含む
├── features/
│ ├── tasks/
│ │ ├── components/ # コンポーネント Atomic Designの粒度で分割 organisms がほとんどになるだろう
│ │ ├── hooks/ # 業務ロジックや状態管理 コンポーネントに依存する場合Atomic Designの粒度で分割
│ │ ├── types/ # 型定義
│ │ └── index.ts # エクスポート用
│ └── ...
├── shared/
│ ├── components/ # 汎用UI Atomic Designの粒度で分割 organisms以下
│ ├── hooks/ # 汎用ロジック コンポーネントに依存する場合Atomic Designの粒度で分割
│ ├── utils/ # 汎用ユーティリティ
│ └── types/ # 汎用型
├── infrastructure/ # APIクライアント
└── lib/ # 外部ライブラリ設定
以上