Доступ к веб-сервису из CQRS
Предположим, у меня есть система на основе CQRS, и для принятия решений моему домену нужны данные из внешнего веб-сервиса. Как мне смоделировать это правильно?
Я могу придумать два варианта:
Обработчик команд запускает логику домена, а сам домен обращается к веб-службе. Получив ответ, он присоединяет соответствующие события к текущему агрегату и сохраняет их. Домен в основном "ждет" возврата веб-службы.
Обработчик команд запускает логику домена, и домен немедленно отправляет внутреннему событию больше данных, необходимых для данных. Менеджер процессов реагирует на это, обращается к веб-службе, реагирует на результат и создает другую команду в первом агрегате, в основном что-то вроде продолжения.
Какой подход "лучше" или оба неправильны, и я должен следовать совершенно другим путем? В принципе, я в порядке с вариантом 1, потому что я думаю, что это в основном не что иное, как длительные вычисления внутри домена, но почему-то идея "ожидания" меня раздражает.
Что я должен делать?
1 ответ
Я склонен думать о своей области так же, как о физическом калькуляторе. Он принимает ввод и производит вывод. Этот вывод может быть сохранен или выдан как события. Таким образом, при поступлении данных происходит некоторое поведение, а при поступлении данных. Так что очень сильно сосредоточены на поведении.
Ваш вариант (1) привел к нескольким дискуссиям DDD о внедрении сервисов или репозиториев (или, я полагаю, антикоррупционного уровня) в сущности. Общее мнение заключается в том, что этого следует избегать, и нужно выбирать, скажем, двойную рассылку. Дело в том, что домену требуется больше информации, и он либо должен быть передан изначально, либо его нужно получить. В моей аналогии с калькулятором получение большего количества данных похоже на калькулятор, запрашивающий дополнительные данные.
Если вы выберете опцию (1), то все, что вызывает домен, должно обрабатывать любой сбой веб-вызова, чтобы повторить попытку.
Если вы выберете вариант (2), в котором вы используете что-то вроде служебной шины и, возможно, своего рода механизм процессов (скажем, saga или workflow), вполне вероятно, что обработчик служебной шины или механизм процесса будет обрабатывать сбои и попытки.
Я не думаю, что одно решение обязательно "лучше", чем другое, а скорее "другое". Я бы выбрал то, что вам удобно, и если у вас уже есть инфраструктура, которая каким-то образом уже связана с отказом / повторной попыткой, я бы выбрал вариант, который легче всего поддерживается этой инфраструктурой.
Надеюсь, это поможет:)