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