マイクロサービスに簡略化された CQRS と DDD のパターンを適用する

ヒント

このコンテンツは、.NET Docs で入手できる、またはオフラインで読み取ることができる無料のダウンロード可能な PDF として入手できる、コンテナー化された .NET アプリケーション用の電子ブックである .NET マイクロサービス アーキテクチャからの抜粋です。

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

CQRS は、データを読み取りと書き込みのモデルを分離するアーキテクチャ パターンです。 関連する用語のコマンド クエリ分離 (CQS: Command Query Separation) は、元々 Bertrand Meyer 氏が著作の『Object Oriented Software Construction』(オブジェクト指向のソフトウェア構築) で定義した用語です。 基本的な考え方は、システムの操作は 2 つの別のカテゴリにはっきりと分けることができるということです。

  • クエリ。 これらのクエリによって結果が返され、システムの状態は変更されません。また、副作用はありません。

  • コマンド。 これらのコマンドによってシステムの状態が変更されます。

CQS はシンプルな概念です。つまり、同じオブジェクト内のメソッドはクエリまたはコマンドである、というものです。 各メソッドは、状態を返すか、状態を変更しますが、両方を行うことはありません。 1 つのリポジトリ パターン オブジェクトでも、CQS に準拠する可能性があります。 CQS は CQRS の基本原則と考えることができます。

コマンド クエリ責務分離 (CQRS: Command and Query Responsibility Segregation) は Greg Young によって導入され、Udi Dahan などによって強く推進されました。 CQRS は CQS の原則に基づいていますが、より詳細です。 コマンドとイベントに加え、必要に応じて非同期メッセージに基づくパターンと考えることができます。 CQRS は多くの場合、書き込み (更新) 用ではなく読み取り (クエリ) 用に異なる物理データベースを持つなど、より高度なシナリオに関連しています。 さらに進化した CQRS システムでは、更新プログラム データベースにイベント ソーシング (ES) を実装することができるため、現在の状態のデータを格納するのではなく、ドメイン モデルにのみイベントを格納します。 ただし、この方法はこのガイドでは使用しません。 このガイドでは、クエリとコマンドを分離するだけの最も単純な CQRS アプローチを使用しています。

CQRS の分離の側面は、あるレイヤーにクエリ操作を、別のレイヤーにコマンドをそれぞれグループ化することによって実現されます。 各レイヤーには独自のデータ モデルがあります (モデルと言っている点に注意してください。必ずしも異なるデータベースではありません)。各レイヤーは独自のパターンとテクノロジの組み合わせを使用して構築されています。 さらに重要な点は、このガイドで使用されている例 (注文マイクロサービス) のように、2 つのレイヤーが同じ階層またはマイクロサービス内に存在する可能性がある、ということです。 また、別のマイクロサービスまたはプロセス上に実装できるので、互いに影響を与えることなく個別に最適化およびスケールアウトすることができます。

CQRS は、他のコンテキストでは 1 つのオブジェクトの場合でも、読み取り/書き込み操作のために 2 つのオブジェクトを持つことを意味します。 非正規化された読み取りデータベースを持つことには理由があります。詳細については、より高度な CQRS のドキュメントを参照してください。 ただし、ここではこのアプローチを使用していません。ここでは、集計のような DDD パターンの制約があるクエリを制限するのではなく、クエリに柔軟性を持たせることを目標としています。

この種のサービスの例として、eShopOnContainers 参照アプリケーションの注文マイクロサービスがあります。 このサービスは、簡略化された CQRS アプローチに基づくマイクロサービスを実装しています。 また、図 7-2 に示すように、単一のデータ ソースまたはデータベースを使用しますが、トランザクション ドメインには 2 つの論理モデルと DDD パターンを使用します。

Diagram showing a high level Simplified CQRS and DDD microservice.

図 7-2。 簡略化された CQRS および DDD ベースのマイクロサービス

この論理的な "注文" マイクロサービスには、注文データベースが含まれています。これは、同じ Docker ホストの可能性もありますが、同じである必要はありません。 同じ Docker ホストにデータベースを置くことは開発の場合にお勧めしますが、運用の場合はお勧めしません。

アプリケーション レイヤーは、Web API の可能性があります。 ここで重要な設計の側面は、マイクロサービスが、CQRS パターンに従って、クエリと ViewModel (特にクライアント アプリケーション用に作成されたデータ モデル) を、コマンド、ドメイン モデル、トランザクションから分離していることです。 このアプローチによって、トランザクションと更新にのみ意味のある DDD パターンに由来する制限と制約から、クエリを独立させることができます。詳細については、以降のセクションで説明します。

その他の技術情報