複雑なビジネスドメインと、REST API(厳密にはRESTではなく、リソース指向)をサポートする要件を持つアプリケーションを設計しようとしています。リソース指向の方法でドメインモデルを公開する方法を考えるのに苦労しています。
DDDでは、ドメインモデルのクライアントは、手続き型「アプリケーションサービス」層を通過して、エンティティおよびドメインサービスによって実装されるビジネス機能にアクセスする必要があります。たとえば、ユーザーエンティティを更新する2つのメソッドを持つアプリケーションサービスがあります。
userService.ChangeName(name);
userService.ChangeEmail(email);
このアプリケーションサービスのAPIは、状態ではなくコマンド(動詞、プロシージャ)を公開します。
ただし、同じアプリケーションにRESTful APIも提供する必要がある場合は、次のようなユーザーリソースモデルがあります。
{
name:"name",
email:"email@mail.com"
}
リソース指向のAPIは、コマンドではなく状態を公開します。これにより、次の懸念が生じます。
REST APIに対する各更新操作は、リソースモデルで更新されているプロパティに応じて、1つ以上のアプリケーションサービスプロシージャコールにマップできます。
各更新操作は、REST APIクライアントにとってアトミックに見えますが、そのようには実装されていません。各アプリケーションサービス呼び出しは、個別のトランザクションとして設計されています。リソースモデルの1つのフィールドを更新すると、他のフィールドの検証ルールが変更される可能性があります。したがって、すべてのリソースモデルフィールドを一緒に検証して、潜在的なすべてのアプリケーションサービスコールが有効になるようにしてから、それらを作成する必要があります。一連のコマンドを一度に検証することは、一度に1つずつ実行することほど簡単ではありません。個々のコマンドが存在することすら知らないクライアントでそれをどのように行うのでしょうか?
アプリケーションサービスメソッドを異なる順序で呼び出すと効果が異なる場合がありますが、REST APIは違いがないように見えます(1つのリソース内)
もっと似たような問題を思いつくかもしれませんが、基本的にはすべて同じことが原因です。アプリケーションサービスを呼び出すたびに、システムの状態が変化します。有効な変更のルール、エンティティが次の変更を実行できるアクションのセット。リソース指向のAPIは、すべてをアトミック操作のように見せようとします。しかし、このギャップを越える複雑さはどこかに行かなければならず、それは巨大なようです。
さらに、UIがよりコマンド指向である場合(多くの場合そうです)、クライアント側でコマンドとリソースをマッピングし、API側に戻す必要があります。
質問:
- このすべての複雑さを(厚い)RESTからAppServiceへのマッピングレイヤーで処理するだけですか?
- または、DDD / RESTの理解に何か不足していますか?
- RESTは、特定の(かなり低い)複雑度でドメインモデルの機能を公開するために、単に実用的ではないでしょうか?