マイクロサービスごとにドメイン モデルの境界を識別する

ヒント

このコンテンツは eBook の「コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ」からの抜粋です。.NET Docs で閲覧できるほか、PDF として無料ダウンロードすると、オンラインで閲覧できます。

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

可能であればマイクロサービスの規模は傾向的に小さくする必要があります。しかしながら、各マイクロサービスのモデルの境界とサイズを識別する場合の目標は、できる限り細かい分離を実現することではありません。 ドメイン知識に従って最も意味のある分離を実現することに目標を設定する必要があります。 重点を置くのはサイズではなく、ビジネス機能です。 加えて、多くの依存関係に基づくアプリケーションの特定の領域に対してクリアな凝集度が必要である場合は、単一のマイクロサービスに対してもそのことが必要になります。 凝集度とは、マイクロサービスをどのように分離またはグループ化するかを識別する方法です。 最終的には、ドメインに関する知識をより多く取得しながら、マイクロサービスのサイズを繰り返し調整する必要があります。 適切なサイズを見つけるには、複数回のプロセスが必要です。

マイクロサービスの推奨者として認知され、書籍『Building Microservices』 (マイクロサービスの構築) の著者でもある Sam Newman 氏は、以前に紹介した Bounded Context (BC) パターン (ドメインドリブン設計の一部) に基づいてマイクロサービスを設計する必要があることを強調しています。 場合によって、1 つの BC を複数の物理サービスで構成することが可能ですが、その逆は成立しません。

具体的な BC またはマイクロサービス内では、特定のドメイン エンティティを持つドメイン モデルが適用されます。 BC によってドメイン モデルの適用性の範囲が定められ、開発チームのメンバーは結束性が必要であるもの、および個別に開発できるものを明確に理解し、その理解を共有することができます。 これらの目標はマイクロサービスと同じです。

適切な設計を知らせてくれる別のツールとして、Conway の法則があります。この法則によれば、アプリケーションは、それを作成した組織のソーシャル境界を反映すると言うことです。 ただし、場合によっては反対のことも言えます。すなわち、会社の組織はソフトウェアによって形成されるということです。 Conway の法則とは反対の方法で、会社の編成方法に応じて境界を構築することが必要な場合があります (ビジネス プロセス コンサルティングへの傾倒)。

境界のあるコンテキストを識別するために、コンテキスト マッピング パターンと呼ばれている DDD パターンを使用できます。 コンテキスト マッピングでは、アプリケーション内の各種コンテキストとその境界を識別します。 たとえば、小規模なサブシステムごとに異なるコンテキストおよび境界を設定するのが一般的です。 コンテキスト マッピングは、ドメイン間のそのような境界を定義し、明示するための方法です。 BC は自律的に機能し、単一ドメインの詳細 (ドメインのエンティティなどの詳細) を含み、その他の BC との統合コントラクトを定義します。 これはマイクロサービスの定義に似ています。マイクロサービスは自律的に機能し、特定のドメインの機能を実装します。また、マイクロサービスはインターフェイスを提供する必要があります。 このため、コンテキスト マッピングと Bounded Context パターンは、マイクロサービスのドメイン モデル境界を識別するのに適した方法となります。

大規模なアプリケーションを設計する場合、そのドメイン モデルをフラグメント化する方法が表示されます。たとえば、カタログ ドメインからのドメイン エキスパートは、カタログ ドメインおよびインベントリ ドメイン内のエントリに、シッピング ドメイン エキスパートとは異なる方法で名前を付けます。 または、顧客に関するすべての詳細を格納する CRM エキスパートに対処する場合と、顧客に関する部分的なデータのみを必要とするオーダリング ドメイン エキスパートに対処する場合とでは、ユーザー ドメイン エンティティの属性のサイズと数が異なる可能性があります。 大規模なアプリケーションに関連するすべてのドメイン間ですべてのドメイン用語を区別するのは非常に困難です。 ただし、最も重要な点は用語の統一を試みるのでなく、 各ドメインによってもたらされる相違点と豊富さを受け入れることです。 アプリケーション全体に対して統一されたデータベースの使用を試みる場合、統一されたボキャブラリの試みには注意を要し、それは複数のドメイン エキスパートのいずれに対しても疑問が生じます。 BC (マイクロサービスとして実装された) を使用すれば、特定のドメイン用語を使用できる場所、およびシステムを分割してそれぞれのドメインで追加の BC を作成する必要が生じる場所を容易に明確にすることができます。

ドメイン モデル間に強力なリレーションシップがほとんどない場合は各 BC およびドメイン モデルの適切な境界とサイズが取得済みであること、および通常のアプリケーション操作を実行する際は複数のドメイン モデルからの情報をマージすることが一般に必要ないことがわかります。

各マイクロサービスのドメイン モデルをどれくらいの大きさにすればよいかという質問に対する最良の回答は、次のようになるでしょう: 自律的な BC (可能な限り分離された) を備えている必要があります。これにより、他のコンテキスト (他のマイクロサービスのモデル) にたびたび切り替えなくても作業が行えます。 図 4-10 では、アプリケーション内で識別された各ドメインに関する特定の要件に応じて、複数のマイクロサービス (複数の BC) のそれぞれで独自のモデルを備える方法、およびそれらのエンティティを定義する方法を確認できます。

Diagram showing entities in several model boundaries.

図 4-10 エンティティとマイクロサービス モデルの境界を識別する

図 4-10 に、オンライン会議管理システムに関連するサンプル シナリオを示します。 境界付けられたコンテキストに応じて、同じエンティティが "ユーザー"、"購入者"、"保険会社"、"顧客" と表示されます。 ドメイン エキスパートが代わりに定義したドメインに基づいて、マイクロサービスとして実装可能な複数の BC を識別しました。 ご覧のように、単一のマイクロサービス モデル内にのみ存在するエンティティがあります ("Payment" マイクロサービス内の "Payments" など)。 それらを実装することは簡単です。

ただし、複数のマイクロサービスからの複数のドメイン モデル間で、シェイプは異なるが同じ識別情報を共有するエンティティが存在する場合もあります。 たとえば、User エンティティは "Conferences Management" マイクロサービスで識別されます。 その同一のユーザー (同一の識別情報が割り当てられた) は "Ordering" マイクロサービスでは "Buyers" という名前になり、"Payment" マイクロサービスでは "Payer" という名前になり、さらに "Customer Service" マイクロサービスでは "Customer" という名前になります。 各ドメイン エキスパートが使用しているユビキタス言語に基づいて、ユーザーは、さまざまな属性も使用して異なる分析観点で見る場合があるために、このようなことが生じます。 "Conferences Management" という名前のマイクロサービス モデルのユーザー エンティティには、その個人データ属性のほとんどが含まれる場合があります。 ただし、"Payment" マイクロサービスの "Payer" のシェイプ内のユーザー、または "Customer Service" マイクロサービスの "Customer" のシェイプ内のユーザーは同じユーザーであっても、同じ属性リストを必要としない場合があります。

同様のアプローチを図 4-11 に示します。

Diagram showing how to decompose a data model into multiple domain models.

図 4-11 従来のデータ モデルを複数のドメイン モデルに分解する

境界付きコンテキストで従来のデータ モデルを分解するとき、同じ ID を共有するエンティティ (バイヤーはユーザーでもあります) でも境界付きコンテキストごとに属性が異なる場合があります。 ユーザーが User エンティティとして "Conferences Management" マイクロサービス モデル内にどのように存在し、また "Pricing" マイクロサービスにも Buyer エンティティの形式でどのように存在しているのか (代替属性か、またはユーザーが実際に購入者である場合のユーザーに関する詳細を使用して) を確認できます。 解決する問題またはコンテキストによっては、各マイクロサービスまたは BC は、User エンティティに関連するすべてのデータを必要とするのでなく、その一部のみを必要とする場合があります。 たとえば、"Pricing" マイクロサービス モデルでは、ユーザーのアドレスも名前も必要なく、ID (識別情報としての) と Status のみを必要とします。このデータは購入者ごとにシートの価格を設定する場合に値引きに影響を与えます。

各ドメイン内で Seat エンティティの名前は同じですが、その属性は異なっています。 ただし、Seat は User および Buyer の場合と同様に、同じ ID に基づいて識別情報を共有します。

基本的には、複数のサービス (ドメイン) に存在するユーザーの共有の概念があります。この概念では、すべてがそのユーザーの識別情報を共有します。 ただし、各ドメイン モデルには、ユーザー エンティティに関する追加のまたは異なる詳細情報が存在する可能性があります。 そのため、あるドメイン (マイクロサービス) から別のドメインにユーザー エンティティをマップする方法が必要です。

ドメイン間で同じユーザー エンティティを同じ数の属性と共有しないことには、いくつかの利点があります。 1 つの利点は重複が少なくなるということです。この結果、マイクロサービス モデルには、必要のないデータが含まれなくなります。 もう 1 つの利点は、エンティティごとに特定の種類のデータを所有するプライマリ マイクロサービスを設定できるということです。これにより、該当する種類のデータに対する更新およびクエリはプライマリ マイクロサービスによってのみ制御されます。