#domain-driven-design #cqrs #axon
Вопрос:
Используя Axon Sramework, каков наилучший способ запуска команды после выполнения другой команды, если она выполнена успешно. Например, команда создаст Aggregate
(а затем сущность, после того как сущность будет создана, нам нужно создать другую совокупность/сущность в другом домене (например, в качестве дочернего элемента первой сущности).
Вторая сущность должна быть создана с помощью команды на агрегате, но где инициировать вторую команду ? в @EventSourcingHandler
первой совокупности ? в @EventHandler
момент сохранения первого объекта ? с помощью Saga
?
Еще один момент/вопрос : каков наилучший способ запуска команды из запроса. Например, у меня есть запрос для получения некоторых записей, и если запись не существует, я хотел бы создать ее автоматически, а затем отправить результат обратно из метода запроса. Должен ли я использовать командный шлюз для отправки команды create из класса обработчика запросов, а затем ждать результата ? или есть другой способ сделать это ?
Спасибо за поддержку и помощь.
Alexandre
Комментарии:
1. Что вы подразумеваете под «например, как дитя первой сущности»? Как эта вторая сущность является дочерней по отношению к первой сущности в другом домене/ограниченном контексте?
Ответ №1:
каков наилучший способ запуска команды после успешной выполнения другой команды?
Игнорируя «лучший способ» в этом вопросе, вы, скорее всего, ищете менеджера процессов. В рамках Аксона они называются Сагами.
Каков наилучший способ запуска команды из запроса. Например, у меня есть запрос на получение некоторых записей, и если запись не существует, я хотел бы создать ее автоматически
Я был бы очень, очень осторожен, делая что-то подобное.
Прежде всего, что делать, если вы получите один и тот же запрос несколько раз за короткое время? Как вы узнаете, была ли команда уже отправлена или нет?
Во-вторых, вы не хотите ждать обновления при ответе на запрос, так как не можете знать, сколько времени это займет и произойдет ли вообще.
Одной из альтернатив является использование запроса подписки. Укажите в первоначальном ответе, что данные неполные, и позвольте клиенту запустить обновление с помощью соответствующего потока команд. Поскольку клиент подписан на запрос, он получит обновление после его завершения.
Ответ №2:
Используя структуру Axon, каков лучший способ инициировать команду после другой команды, если она выполнена успешно. Например, команда создаст агрегат (а затем сущность,9 после того, как сущность будет создана, нам нужно создать другую совокупность/сущность в другом домене (например, в качестве дочернего элемента первой сущности).
Во-первых, команда НИКОГДА не создает агрегат. Команда определяет намерение создать агрегат. Конструктор команд должен проверить, выполнены ли все условия для создания агрегата, а затем отправить событие, созданное агрегатом. Это событие фактически создает агрегат и инициализирует его состояние. Более подробную информацию об этом см. в документации Axon для команд и событий. Обратите также внимание, что в хранилище событий хранятся только события, команды запускаются и забываются.
Событие, созданное агрегатом, отправленное агрегатом, может создать сущность, например, с помощью обработчика событий в проекции (я предполагаю, что сущность существует в области проекции в модели чтения).
Поскольку вы упомянули, что за созданием сущности следует создание другой совокупности, в игру вступают саги (как упоминал Милен). Сага запускается событием, созданным событием первого агрегата, и отправляет команду создания для второго агрегата. Затем повторяется тот же поток, что и для первого агрегата (проверьте все условия для создания агрегата и отправьте событие создания).
Если вам нужна гарантия того, что первая сущность существует до того, как будет создана вторая совокупность, вы можете попытаться отправить своего рода событие, созданное первой сущностью, в проекции, поймать это событие в своей саге и позволить этому обработчику саги запустить команду для создания второй совокупности. Я не знаю наверняка, разрешено ли проекции отправлять команды, хотя я не могу себе представить, почему бы и нет… События домена могут использоваться для пересечения границ микросервиса.
Это звучит сложнее, чем есть на самом деле, но обязательно ознакомьтесь с главой о сагах в документах Axon.
Вторая сущность должна быть создана с помощью команды на агрегате, но где инициировать вторую команду ? в обработчике @EventSourcing первого агрегата ? в @EventHandler при сохранении первого объекта ? используя Сагу ?
Я думаю, что немного странно создавать сущности с помощью команд в совокупности. Агрегаты обрабатывают команды, связанные с изменениями состояния, которые они допускают с точки зрения бизнеса. Каково ваше намерение сделать это? Сущности (предполагая, что вы имеете в виду сущности JPA), как упоминалось ранее, используются для «обобщения» всех событий, которые приводят к текущему состоянию агрегата, и часто живут в модели чтения (в архитектуре CQRS). @EventHandlers обычно прослушивают события и соответствующим образом обновляют сущность в проекции. @EventSourcingHandler работает в агрегате, чтобы реагировать на события для обновления текущего состояния агрегата, которое должно быть известно для проверки правильности будущих команд. Команды очень тесно связаны с действиями, связанными с бизнес-процессами, выполняемыми в совокупности.
Я надеюсь, что это немного прояснит ваши вопросы, хотя я боюсь, что они просто создадут больше вопросов 😉