モジュラーモノリス

モノリスの内部をモジュールに分割し、マイクロサービスの利点を取り入れたアーキテクチャ

アーキテクチャ設計

モジュラーモノリスとは

モジュラーモノリスは、単一のデプロイ単位 (モノリス) の内部を明確なモジュール境界で分割し、マイクロサービスが持つ疎結合と責務の分離を、モノリスの利点 (単一のデプロイ単位、プロセス内で完結するトランザクション) を保ったまま得ようとするアーキテクチャである。独立してデプロイできることはデプロイ単位を分けたことの帰結であり、単位が 1 つのモジュラーモノリスでは得られない。

モノリス vs モジュラーモノリス vs マイクロサービス

3 者の差はデプロイ単位の数だけではない。本質は境界を何が強制するかで、マイクロサービスではプロセスとネットワークが物理的に強制するのに対し、モジュラーモノリスは全モジュールが同じプロセスに同居するため、規約と静的検査だけが強制手段になる。

観点モノリスモジュラーモノリスマイクロサービス
デプロイ1 つ1 つサービスごと
モジュール境界曖昧明確プロセス境界
通信関数呼び出し公開 API 経由ネットワーク
トランザクション容易容易分散トランザクション
運用の複雑さ低い低い高い

モジュールの設計

モジュールごとに公開 API のファイルを 1 つだけ置き、残りを内部実装として扱う構成が基本形になる。ディレクトリを分けること自体は境界にならない。api.ts を経由しない import を機械的に弾けるかどうかが分かれ目である。

my-app/
├── modules/
│   ├── orders/
│   │   ├── api.ts        # 公開 API (他モジュールからのアクセス点)
│   │   ├── service.ts    # ビジネスロジック (内部)
│   │   └── repository.ts # データアクセス (内部)
│   ├── users/
│   │   ├── api.ts
│   │   ├── service.ts
│   │   └── repository.ts
│   └── payments/
│       ├── api.ts
│       ├── service.ts
│       └── repository.ts
└── shared/               # 共通の型、ユーティリティ

モジュール間の通信ルール

通信ルールは文書に書くだけでは守られない。ESLint の no-restricted-imports のように import のパスを制限する検査へ載せ、レビューでの口頭指摘に頼らない形にしておく。

// ✅ 公開 API 経由でアクセス
import { getUserById } from '../users/api';

// ❌ 内部の実装に直接アクセス (禁止)
import { userRepository } from '../users/repository';

イベントによる疎結合

同期的な呼び出しを避けたい場合はイベントを介する。ただしこれは依存が消えるのではなく、import 文による依存をイベント名とペイロードの形という契約へ移す操作である。

// orders モジュール: イベントを発行
eventBus.emit('order.created', { orderId: '123', userId: 'abc' });

// payments モジュール: イベントを購読
eventBus.on('order.created', async (event) => {
  await createPayment(event.orderId);
});
// orders は payments を import しない

同一プロセスのイベントバスは、メッセージキューのような失敗の分離を与えない。Node.js の EventEmitter は登録順にリスナーを同期実行して戻り値を捨てるため、上の例のように async のリスナーを登録すると createPayment の失敗は発行側へ伝わらず、未処理の Promise 拒否になる (コンストラクターの captureRejections は既定で無効)。決済の失敗を注文側で扱う必要があるなら、公開 API 経由の呼び出しにするか、失敗したイベントを記録して再試行する仕組みを用意する。

いつモジュラーモノリスを選ぶか

選択は人数だけで決まらない。ドメイン境界が見えていない段階で分割すると、境界の引き直しがモジュールの移動ではなくサービス間の移設に化ける。判断の目安を以下にまとめる。

ケース推奨
新規プロジェクトモジュラーモノリスから始める
チーム 1〜3 人モジュラーモノリス
ドメイン境界が不明確モジュラーモノリス (後で分割)
チーム 10 人以上、独立デプロイが必要マイクロサービス

モジュラーモノリスについては関連書籍でも詳しく扱われている。

この記事は役に立ちましたか?

関連用語

関連する記事