現時点では、CQRS とドメイン駆動設計の原則に基づく新しいアーキテクチャを構築しています。現在、外部とのコミュニケーションをどのように扱うべきかについて議論を行っています。質問をより具体的にするために、顧客が注文を作成したときに SMS 通知を送信する例を使用します。
クライアントは、関連付けられたコマンド ハンドラーによって処理される NewOrderCommand を作成します。ハンドラーは、ドメイン モデルに新しい Order オブジェクトを作成し、NewcustomerCreatedEvent を生成します。オブジェクトはイベント ストアに保存され、イベントはすべてのリスナーに発行されます。
ここまでは順調ですが、ここで質問です。SMS 通知はどこに送信すればよいですか?
私たちの最初の本能は、NewCustomerCreatedEvent をリッスンしてメッセージを送信するイベント リスナーを使用して送信する必要があることを教えてくれました。このアプローチの問題点は、SMS の送信もビジネス ロジックの一部であることです。私たちはホストされたサービスを販売しているので、クライアントは彼らに代わって送信されたすべての SMS メッセージを見ることができるはずです. メッセージの送信はドメイン外で行われるため、それを行うことはできません。
SMS ドメインを作成し、イベント リスナーが NewCustomerCreatedEvent を受け取ると、イベント ハンドラーが新しいコマンド SendSmsMessageCommand を作成します。このコマンドは、ドメイン内に新しい SMSMessage オブジェクトを作成し、SMS 通知を送信して、SmsSent イベントを作成します。見る。
最初はドメイン モデルで SMS メッセージを送信していましたが、これが問題を引き起こす可能性があることに気付きました。SMS の送信後に何かが発生し (例外がスローされ)、トランザクションがロールバックされたとします。私たちのドメインはこれを完全にサポートしているため、データに関しては問題ありませんが、SMS メッセージは既に送信されているため、コマンドが再送信されると、SMS 通知が再度送信されます。
SmSSent イベントで SMS を送信することを考えていましたが、それは少し奇妙です。イベントは、メッセージが既に送信されたと言っているのに、まだ送信されていないからです。
上記の例から、CQRS とドメイン駆動設計の概念で外部通信をどのように処理するかという疑問が生じます。SMS 通知の送信だけでなく、請求書の送信、外部請求システム、および外部世界へのその他すべての種類の通信についても話しています。これはビジネス ロジックであるため、ドメインで行うべきでしょうか、それともイベント ハンドラーのイベントに基づいて常に行うべきでしょうか? また、そうする場合、メッセージがまだ実際に送信されていないときにメッセージが送信されたことを示すイベントを使用することは許容されますか?
皆さんがすでにこの状況に対処しており、この件についてアドバイスをいただけることを願っています。