Прочитать сторонние подходы к реализации с использованием CQRS

Я перешел в проект, который активно использует CQRS + event sourcing. С первого взгляда он реализовывался в соответствии со всеми этими книгами и блогами, но, в конце концов, я понял, что именно выглядит в процессе реализации.

Вот архитектура CQRS: CQRS design

Изначально я сделал это изображение из здесь.

Как видно на рисунке, сторона чтения получает события из очереди и передает ее по одному в разные наборы проекций (denormalizers), а затем полученные ViewModels сохраняются через метод AddOrUpdate, скажем, в DB. Так как я понимаю из изображения denormalizer может полагаться только на само событие плюс данные со стороны db на стороне чтения. Например:

  • Просмотр аккаунта уже сохранен в db.
  • Придет событие EmailChanged
  • Мы читаем "Просмотр учетной записи" из базы данных
  • Применение изменения электронной почты к ней
  • Мы сохраняем счет обратно в БД.

Другой случай (подсчет количества некоторых элементов, например заказов):

  • Прикрепленное событие OrderCreated
  • Мы читаем ViewModel, который представляет NumberOf ранее поступившие заказы
  • Увеличить и сохранить это.

Что мы имеем в нашем проекте: Мы используем все эти события только как уведомитель, что что-то изменилось в модели домена. Следовательно, что мы делаем:

  • Мы берем репозиторий домена и читаем все необходимые агрегаты. Таким образом, мы получаем самое последнее из них.
  • Мы просто создаем объект ViewModel с нуля
  • Сохранить вновь созданный объект в Db

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

Если мы используем подход из книг, мне придется иметь отдельную логику utils где-то из моей системы для перестройки. Что нам нужно для этого:

  • Отбросить прочитанную сторону
  • С самого начала прочитайте все события из хранилища событий.
  • Пропустите их через проекции

Итак, мой вопрос:
Каков правильный подход?

Ответы

Ответ 1

Подход, который мы используем в нашем проекте, выглядит немного странным для меня, я не могу все его недостатки.

Одним из важных недостатков является то, что после получения события вы должны сделать дополнительный вызов в репозиторий соответствующего агрегата. Это означает, что этот репозиторий должен быть открыт либо напрямую, либо как услуга. В дополнение к увеличенным зависимостям является дополнительным IO.

Для восстановления из хранилища событий описанный вами подход является общепринятым методом. В описанном ниже подходе используется журнал событий, посвященный перестройке прогнозов. Это можно использовать для решения проблем производительности при восстановлении. Также взгляните на Масштабируемые и простые представления CQRS в облаке и на Список рассылки DDD/CQRS.