古典的な顧客限定コンテキストとMakeCustomerPreferred
コマンドがあり、ロギングや認可などのクロスカッティングの問題があるとします。このようなクロスカッティングの問題を扱う方法は広範囲に議論されてきましたが、ドメインイベント自体でコマンドを発行する責任を負うユーザーまたはサービスに関する情報を記録したい場合があります。CQRS/ESシステムでイベントを発行しているサービスとユーザの録音
例イベント:
interface CustomerMadePreferred {
customerId: string,
issuingService: string,
issuingUser: string,
}
コマンド例:私たちの上のコマンドを使用して
interface MakeCustomerPreferred {
customerId: string
}
は、発行ユーザとサービスの詳細をコンテキストに欠けるでしょう。コマンドの一部としてクライアントにissuingService
とissuingUser
の値を指定する必要があるかもしれませんが、問題は一般にクライアントから送信されたコマンドであり、クライアントがアプリケーションの制御外のWebブラウザであると想定できますユーザーがコマンド内で送信できる値を制御することはできません。さらに、OASuthトークンなどを使用してReSTfulまたはJSON Web APIの背後にサービスがある場合、これらの値を一般的に判断できます。これは私にいくつかの明白な戦略を残す。
可能な戦略:
- 認証コンテキストから決定された値と照合して検証し、その後のコマンドで
issuingService
とissuingUser
を含めると。これにより、クライアントから発行されたコマンドは、ハンドラによって処理されたものと同一になり、コマンドパラメータのみが必要であり、認証コンテキストが渡されないという点で、ハンドラ実装が単純になります。 issuingService
およびissuingUser
auth contextそれらの詳細をコマンドハンドラに渡されたコマンドに追加/注入する。これにより、元のコマンドを発行しているクライアントが簡単になりますが、コマンドハンドラとクライアントの間でコマンドのコントラクトが少し異なります。例:Object.assign({}, makeCustomerPreferredCommand, authContext);
- authコンテキストをコマンドハンドラとは別の引数として渡すか、コマンドハンドラから呼び出せるサービスからauthコンテキストを渡すことができます。これにより、コマンドの契約は保持されますが、コマンドハンドラの実装は複雑になります。
私はコマンドハンドラの実装に機能的なアプローチを可能にすると思われる主な理由のオプションとに傾いています。多分、私はいくつかのオプションを除外しているか、またはイベントに不要なものとしてissuingService
とissuingUser
を含むいくつかの詳細を見落としています。
UPDATE:代替、オプションそれを呼び出す生成イベントをCustomerMadePreferred、代わりに処理し、そのいくつかの並べ替えのキーが含まれている可能性があり、別CommandIssued
イベントを発行してこれらの詳細を含まないようにすることができます発行者情報を、コマンドハンドラによって発行されたイベントと関連付けるために使用することができる。
テクニカル実装では、同じ問題について考えているときに、予定にメタデータを追加することを計画しています。したがって、イベントはドメインオブジェクトのままですが、コンテキストを特定するために技術的なメタデータを添付することができます。 –
@jpierson 2と3の間に違いはありません。*コマンドハンドラとクライアント*の間でコマンドが若干異なりますか? – guillaume31
@ guillaume31では、2と3の違いはおそらく微妙ですが、これらのコマンド・タイプを取り巻くユニット・テストやコマンド・タイプを取り巻く他の反射型ツールをどのように書くかについては、大きな影響を受けます。コマンドハンドラのクラス/関数の契約もまた影響を受ける。 – jpierson