モジュラーモノリス
モノリスの内部をモジュールに分割し、マイクロサービスの利点を取り入れたアーキテクチャ
アーキテクチャ設計
モジュラーモノリスとは
モジュラーモノリスは、単一のデプロイ単位 (モノリス) の内部を明確なモジュール境界で分割し、マイクロサービスの利点 (疎結合、独立した開発) をモノリスの利点 (シンプルなデプロイ、トランザクション) と両立させるアーキテクチャである。
モノリス vs モジュラーモノリス vs マイクロサービス
| 観点 | モノリス | モジュラーモノリス | マイクロサービス |
|---|---|---|---|
| デプロイ | 1 つ | 1 つ | サービスごと |
| モジュール境界 | 曖昧 | 明確 | プロセス境界 |
| 通信 | 関数呼び出し | 公開 API 経由 | ネットワーク |
| トランザクション | 容易 | 容易 | 分散トランザクション |
| 運用の複雑さ | 低い | 低い | 高い |
モジュールの設計
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/ # 共通の型、ユーティリティ
モジュール間の通信ルール
// ✅ 公開 API 経由でアクセス
import { getUserById } from '../users/api';
// ❌ 内部の実装に直接アクセス (禁止)
import { userRepository } from '../users/repository';
イベントによる疎結合
// orders モジュール: イベントを発行
eventBus.emit('order.created', { orderId: '123', userId: 'abc' });
// payments モジュール: イベントを購読
eventBus.on('order.created', async (event) => {
await createPayment(event.orderId);
});
// モジュール間の直接依存がない
いつモジュラーモノリスを選ぶか
| ケース | 推奨 |
|---|---|
| 新規プロジェクト | モジュラーモノリスから始める |
| チーム 1〜3 人 | モジュラーモノリス |
| ドメイン境界が不明確 | モジュラーモノリス (後で分割) |
| チーム 10 人以上、独立デプロイが必要 | マイクロサービス |
モジュラーモノリスについては関連書籍でも詳しく扱われている。