В данный момент мы создаем новую архитектуру, основанную на принципах CQRS и доменного проектирования. Сейчас у нас есть некоторые дискуссии о том, как мы должны иметь дело с внешним общением. Чтобы конкретизировать вопрос, я использую пример отправки SMS-уведомления, когда клиент создает заказ.
Клиент создает NewOrderCommand, который обрабатывается связанным обработчиком команд. Обработчик создает новый объект Order в доменной модели, который генерирует NewcustomerCreatedEvent. Объект сохраняется в хранилище событий, а событие публикуется для всех слушателей.
Пока все хорошо, но теперь вопрос. Куда нам отправлять смс-уведомление?
Наш первый инстинкт сказал нам, что мы должны отправить его, используя прослушиватель событий, который прослушивает NewCustomerCreatedEvent и отправляет сообщение. Проблема этого подхода заключается в том, что отправка SMS также является частью нашей бизнес-логики. Мы продаем размещенные сервисы, чтобы наши клиенты могли видеть все SMS-сообщения, отправленные от их имени. Поскольку отправка сообщения происходит за пределами домена, мы не можем этого сделать.
Итак, мы создали домен SMS, и теперь, когда прослушиватель событий получает NewCustomerCreatedEvent, обработчик событий создает новую команду SendSmsMessageCommand, которая создаст новый объект SMSMessage в нашем домене, отправит SMS-уведомление и создаст событие SmsSent, которое мы используем. создать вид.
Сначала мы отправляли SMS-сообщение в доменной модели, но мы поняли, что это может вызвать некоторые проблемы. Допустим, что после отправки SMS что-то происходит (выдается исключение) и транзакция откатывается. Наш домен полностью поддерживает это, поэтому с данными все в порядке, но SMS-сообщение уже отправлено, поэтому при повторной отправке команды SMS-уведомление будет отправлено снова.
Мы думали об отправке SMS на событие SmSSent, но это было бы немного странно, потому что событие говорит, что сообщение уже отправлено, но это не так.
Приведенный выше пример подводит нас к вопросу о том, как обращаться с внешней связью в концепции CQRS и доменного проектирования? Мы говорим не только об отправке SMS-уведомлений, но и об отправке счетов и внешней биллинговой системы, а также всех других видов связи с внешним миром. Должны ли мы делать это в области, потому что это бизнес-логика, или мы всегда должны делать это на основе событий в наших обработчиках событий? И если мы сделаем это, допустимо ли использовать события, которые сообщают, что сообщение отправлено, когда оно еще не сделано?
Надеюсь, вы, ребята, уже справились с этой ситуацией и можете дать нам несколько советов по этому вопросу.