Published on

アプリのDIR構成とクリーンアーキテクチャなど

Authors
  • avatar
    Name
    Kikusan
    Twitter

フロントエンド・バックエンド分離構成のときのDIR構成の悩みポイントを記載。

アーキテクチャについて

レイヤードアーキテクチャ

技術的な関心ごとの切り口。 以下の流れで上から下に依存関係を構築する。(層の名前はアプリごとにn個あって良い) モノリシックなデプロイメントの性質を持つ。

  1. presentation層:ユーザインタフェースをバックエンドとの通信ロジックに責任がある
  2. application層:ユースケース毎にドメインオブジェクトの操作を行う
  3. domain層:ドメイン毎にビジネスロジックを実装する。
  4. 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/                  # 外部ライブラリ設定

以上