Прочитать сторонние подходы к реализации с использованием 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.