Как отправить ответ на команду в CQRS?

Я реализую систему CQRS с постоянством Akka и пытаюсь понять бит ответа на запрос CQRS.

На SO есть несколько ответов о том, как отправить ответ обратно клиенту, и эта статья также упоминает несколько хороших шаблонов. Но вместо того, чтобы обобщать, используя громкие слова, может кто-нибудь объяснить, как мне отправить ответ клиенту в CQRS для следующего простого варианта использования.

Случай использования

Предположим, что пользователь находится на странице, которая отображает профиль пользователя, который отображает следующую информацию

  1. Имя пользователя
  2. Адрес
  3. Телефонный номер

И в моей системе у меня есть один актер на пользователя, который хранит информацию о профиле этого пользователя.

В пользовательском интерфейсе пользователь хочет обновить адрес, и происходит следующее:

  1. Пользователь делает вызов AJAX REST для обновления адреса пользователя
  2. UpdateUserAddressCommand(address:String) сгенерировано
  3. UpdateUserAddressEvent(address:String) сгенерировано
  4. UserAddressUpdatedEvent(updatedAddress:String) сгенерировано (состояние UserActor обновлено)

Теперь, как мне отправить обратно полное состояние UserProfile в системе? Поскольку CQRS не рекомендует отправлять ответ на команду?


person captain-inquisitive    schedule 18.10.2015    source источник


Ответы (1)


Что касается шаблона CQRS, уровень REST можно рассматривать как клиент системы, использующей CQRS, и поэтому вы можете отправлять ответ (от сервера REST в веб-браузер), не нарушая «принципа».

В вашем случае все очень просто:

  1. Вызов REST на /api/endpoint/1234 -> сервер REST генерирует команду, как указано выше.
  2. Сервер возвращает код «202 Accepted» и устанавливает для заголовка Location: что-то вроде /api/user/profile/1234.
  3. Клиент запрашивает /api/user/profile/1234, чтобы запросить полное состояние файла UserProfile.

Вы можете комбинировать 3. с длинным опросом HTTP, если вы используете асинхронные обновления на стороне запроса/согласованность в конечном итоге.

person Alexander Langer    schedule 18.10.2015
comment
В этом есть смысл. Спасибо :) А как насчет сообщений об ошибках? Они также обрабатываются таким образом или отправка ошибок, таких как недействительный адрес в самой команде, также противоречит шаблону CQRS? - person captain-inquisitive; 18.10.2015
comment
Общее эмпирическое правило заключается в том, чтобы избегать ошибок в обработчиках команд. В случае ошибок ввода, таких как недействительный адрес, клиент (уровень REST) ​​может выполнить преждевременную проверку, чтобы избежать ошибок в обработчике команд. В случае возникновения бизнес-ошибок (таких как дублирование адресов/пользователей и т. д.), которые нельзя обнаружить простой проверкой, вместо этого следует реализовать компенсирующие действия. Если они случаются редко, возможно, имеет смысл выполнить компенсацию/исправление вручную. - person Alexander Langer; 19.10.2015
comment
Если производительность не является критической проблемой, почему бы обработчику команд не отвечать клиенту? Тайм-аут можно использовать для возврата к состоянию 202 Accepted в качестве особого случая, если, скажем, высокая нагрузка не позволяет проверить весь цикл за разумное время. В противном случае создается впечатление, что модель предметной области действительно взорвется, если вам придется учитывать множество постоянных состояний ошибок, которые впоследствии необходимо исправить. Или, может быть, я неправильно понимаю, что вы подразумеваете под компенсационными действиями. - person acjay; 31.10.2015