マイクロサービスに簡略化された CQRS と DDD のパターンを適用するApply simplified CQRS and DDD patterns in a microservice

CQRS は、データを読み取りと書き込みのモデルを分離するアーキテクチャ パターンです。CQRS is an architectural pattern that separates the models for reading and writing data. 関連する用語のコマンド クエリ分離 (CQS: Command Query Separation) は、元々 Bertrand Meyer 氏が著作の『Object Oriented Software Construction』(オブジェクト指向のソフトウェア構築) で定義した用語です。The related term Command Query Separation (CQS) was originally defined by Bertrand Meyer in his book Object Oriented Software Construction. 基本的な考え方は、システムの操作は 2 つの別のカテゴリにはっきりと分けることができるということです。The basic idea is that you can divide a system's operations into two sharply separated categories:

  • クエリ。Queries. クエリは結果を返し、システムの状態を変更しません。また、副作用がありません。These return a result and do not change the state of the system, and they are free of side effects.

  • コマンド。Commands. コマンドはシステムの状態を変更します。These change the state of a system.

CQS はシンプルな概念です。つまり、同じオブジェクト内のメソッドはクエリまたはコマンドである、というものです。CQS is a simple concept: it is about methods within the same object being either queries or commands. 各メソッドは、状態を返すか、状態を変更しますが、両方を行うことはありません。Each method either returns state or mutates state, but not both. 1 つのリポジトリ パターン オブジェクトでも、CQS に準拠する可能性があります。Even a single repository pattern object can comply with CQS. CQS は CQRS の基本原則と考えることができます。CQS can be considered a foundational principle for CQRS.

コマンド クエリ責務分離 (CQRS: Command and Query Responsibility Segregation) は Greg Young によって導入され、Udi Dahan などによって強く推進されました。Command and Query Responsibility Segregation (CQRS) was introduced by Greg Young and strongly promoted by Udi Dahan and others. CQRS は CQS の原則に基づいていますが、より詳細です。It is based on the CQS principle, although it is more detailed. コマンドとイベントに加え、必要に応じて非同期メッセージに基づくパターンと考えることができます。It can be considered a pattern based on commands and events plus optionally on asynchronous messages. CQRS は多くの場合、書き込み (更新) 用ではなく読み取り (クエリ) 用に異なる物理データベースを持つなど、より高度なシナリオに関連しています。In many cases, CQRS is related to more advanced scenarios, like having a different physical database for reads (queries) than for writes (updates). さらに進化した CQRS システムでは、更新プログラム データベースにイベント ソーシング (ES) を実装することができるため、現在の状態のデータを格納するのではなく、ドメイン モデルにのみイベントを格納します。Moreover, a more evolved CQRS system might implement Event-Sourcing (ES) for your updates database, so you would only store events in the domain model instead of storing the current-state data. ただし、この方法はこのガイドでは使用しません。However, this approach is not used in this guide. このガイドでは、クエリとコマンドを分離するだけの最も単純な CQRS アプローチを使用しています。This guide uses the simplest CQRS approach, which consists of just separating the queries from the commands.

CQRS の分離の側面は、あるレイヤーにクエリ操作を、別のレイヤーにコマンドをそれぞれグループ化することによって実現されます。The separation aspect of CQRS is achieved by grouping query operations in one layer and commands in another layer. 各レイヤーには独自のデータ モデルがあります (モデルと言っている点に注意してください。必ずしも異なるデータベースではありません)。各レイヤーは独自のパターンとテクノロジの組み合わせを使用して構築されています。Each layer has its own data model (note that we say model, not necessarily a different database) and is built using its own combination of patterns and technologies. さらに重要な点は、このガイドで使用されている例 (注文マイクロサービス) のように、2 つのレイヤーが同じ階層またはマイクロサービス内に存在する可能性がある、ということです。More importantly, the two layers can be within the same tier or microservice, as in the example (ordering microservice) used for this guide. また、別のマイクロサービスまたはプロセス上に実装できるので、互いに影響を与えることなく個別に最適化およびスケールアウトすることができます。Or they could be implemented on different microservices or processes so they can be optimized and scaled out separately without affecting one another.

CQRS は、他のコンテキストでは 1 つのオブジェクトの場合でも、読み取り/書き込み操作のために 2 つのオブジェクトを持つことを意味します。CQRS means having two objects for a read/write operation where in other contexts there is one. 非正規化された読み取りデータベースを持つことには理由があります。詳細については、より高度な CQRS のドキュメントを参照してください。There are reasons to have a denormalized reads database, which you can learn about in more advanced CQRS literature. ただし、ここではこのアプローチを使用していません。ここでは、集計のような DDD パターンの制約があるクエリを制限するのではなく、クエリに柔軟性を持たせることを目標としています。But we are not using that approach here, where the goal is to have more flexibility in the queries instead of limiting the queries with constraints from DDD patterns like aggregates.

この種のサービスの例として、eShopOnContainers 参照アプリケーションの注文マイクロサービスがあります。An example of this kind of service is the ordering microservice from the eShopOnContainers reference application. このサービスは、簡略化された CQRS アプローチに基づくマイクロサービスを実装しています。This service implements a microservice based on a simplified CQRS approach. また、図 7-2 に示すように、単一のデータ ソースまたはデータベースを使用しますが、トランザクション ドメインには 2 つの論理モデルと DDD パターンを使用します。It uses a single data source or database, but two logical models plus DDD patterns for the transactional domain, as shown in Figure 7-2.

簡略化された CQRS と DDD マイクロサービスの概要を示す図

図 7-2Figure 7-2. 簡略化された CQRS および DDD ベースのマイクロサービスSimplified CQRS- and DDD-based microservice

この論理的な "注文" マイクロサービスには、注文データベースが含まれています。これは、同じ Docker ホストの可能性もありますが、同じである必要はありません。The Logical "Ordering" Microservice includes its Ordering database, which can be, but doesn't have to be, the same Docker host. 同じ Docker ホストにデータベースを置くことは開発の場合にお勧めしますが、運用の場合はお勧めしません。Having the database in the same Docker host is good for development, but not for production.

アプリケーション レイヤーは、Web API の可能性があります。The application layer can be the Web API itself. ここで重要な設計の側面は、マイクロサービスが、CQRS パターンに従って、クエリと ViewModel (特にクライアント アプリケーション用に作成されたデータ モデル) を、コマンド、ドメイン モデル、トランザクションから分離していることです。The important design aspect here is that the microservice has split the queries and ViewModels (data models especially created for the client applications) from the commands, domain model, and transactions following the CQRS pattern. このアプローチによって、トランザクションと更新にのみ意味のある DDD パターンに由来する制限と制約から、クエリを独立させることができます。詳細については、以降のセクションで説明します。This approach keeps the queries independent from restrictions and constraints coming from DDD patterns that only make sense for transactions and updates, as explained in later sections.

その他の技術情報Additional resources

  • Greg Young。「Versioning in an Event Sourced System」 (オンライン電子書籍で無料提供) Greg Young. Versioning in an Event Sourced System (Free to read online e-book)
    https://leanpub.com/esversioning/read