コマンドは何も返すべきではないことを理解しています。
それは一つの見方ですが、完全に固まっているわけではありません。HTTPでの書き込み(PUT、POST、DELETE)を検討してください-これらのメッセージはすべて、リソースが状態を変更するという要求を伴うメッセージであるという意味でコマンドであり、すべてが応答を返します。
それでは、コマンドバス以外のエラーをどのように処理しますか?(たとえば、同じユーザー名/メールで1秒前に登録したユーザー)。
そのコマンドが失敗したことをどのようにして知り、どのようにしてエラーを知っていますか?
したがって、コマンドハンドラーと直接通信している場合、返されたメッセージは、コマンドが受信され処理されたことを確認するための完全に合理的な方法です。
ターゲットと直接通信できないようにするバスなどのミドルウェアを使用している場合は、非同期メッセージングパターンに注目することをお勧めします。コマンドハンドラを取得してメッセージを呼び出し元?
1つのアイデアは、コマンドの結果をサブスクライブすることです。これは、Hohpeのエンタープライズ統合パターンのアイデアの一部を借用しています。基本的な考え方は、クライアントは送信されたコマンドメッセージに精通しているため、コマンドメッセージの結果として発行された新しいメッセージをサブスクライブする適切な位置にあるということです。コマンドハンドラーは、データを記録帳に保存した後、変更が成功したことを通知するイベントを発行し、クライアントはそれらのイベントにサブスクライブします-メッセージ内のさまざまな識別子の一致を考慮して正しいイベントを認識します相関IDなど)。
代替アプローチはもう少し直接的です。1つは、メッセージにコールバックを含めることです。コールバックは、メッセージが正常に処理された後にコマンドハンドラーによって呼び出すことができます。
非常によく似た代替方法は、コマンドハンドラーが確認応答を書き込むためにコマンドメッセージにスペースを予約することです。クライアントには問題のコマンドメッセージが既にあるため、回線は既に完了しています。「約束」または「完全な未来」を考えてください。 メッセージは、コマンドハンドラに確認応答を書き込む場所を指示します。これにより、確認応答が利用可能であることをクライアントに通知します(カウントダウンラッチ)。
もちろん、ミドルウェアを削除する追加オプションがありますが、これは単純に正しいことを行うのを妨げているようです。
たとえば、1秒前に同じユーザー名/メールアドレスで登録したユーザー
ユーザー登録をべき等で処理している場合、それは必ずしもエラーではありません。応答が確認されるまでメッセージを繰り返すことが、少なくとも1回の配信を保証する一般的な方法です。