Проверка события

Мы рассматриваем возможность внедрения шаблона CQRS на работе и у нас есть пара вопросов о проверке.

Допустим, у нас есть 3 совокупных корня:

  • User
  • Business
  • UserToBusinessRelationship

Когда пользователь регистрируется, отправленные события будут следующими:

UserCreated
BusinessCreated
UserAddedToBusiness

События должны быть проверены, например, для создания связи между пользователем и бизнесом должны быть созданы и пользователь, и бизнес.

Я вижу два подхода.

  1. Предварительная проверка: создавайте модель чтения на лету, используя последний обработанный снимок плюс необработанные события, и используйте ее для проверки.

  2. Проверка при обработке: принимайте события/команды как есть и выполняйте проверку при обработке событий.

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

Я думал о чем-то вроде этого: когда вы создаете событие, вы возвращаете идентификатор, который вы можете позже использовать для запроса статуса события. Если обработка события прошла успешно, вы получите «ОК», в противном случае вы получите сообщение об ошибке, указывающее, что пошло не так.

Это правильный подход или излишество? Как потребитель узнает, что событие обработано и данные готовы к использованию?


person Leonti    schedule 22.06.2017    source источник
comment
Что вы подразумеваете под валидацией событий? В CQRS проверяются только команды; после того, как они приняты и сгенерировано событие, эти события должны быть приняты, они считаются очень действительными, они представляют собой факты, которые уже произошли.   -  person Constantin Galbenu    schedule 22.06.2017
comment
Возможно, ответ на ваш вопрос находится здесь: danielwhittaker.me/2014/11/22/   -  person Vladislav Ihost    schedule 23.06.2017


Ответы (2)


Отличный вопрос, Леонти. Возможно, вам будет полезен мой пост в блоге о проверке в системе CQRS. Вы можете найти это здесь: Как Проверка команд в приложении CQRS.

Просто обратите внимание на заголовок, что акцент в CQRS делается на проверку команд, а не событий.

Почему?

Потому что команда может исходить от пользовательского ввода, и поэтому ей нельзя доверять. События, с другой стороны, генерируются внутри домена, и им можно доверять. Могут быть реализации CQRS, в которых события покидают пределы системы или получают события, которые не исходят из системы. В этих крайних случаях следует проявлять осторожность.

Еще один потенциальный красный флаг — это то, как вы описали свои агрегаты. Мне кажется (и я не знаю вашего домена, поэтому не могу быть уверен на 100%), что они больше похожи на таблицы в базе данных, чем на агрегаты. Важно не позволять тому, как ваш механизм постоянства диктует ваши модели.

Возвращаясь к вашему вопросу более конкретно.

Вообще говоря, есть 2 типа проверки. Поверхностный и глубокий. Поверхностные — это такие вещи, как отсутствующие поля, действительные адреса электронной почты и т. д. Глубокие — это когда в игру вступает концепция домена. например требуется вес груза и поверхностная проверка, но вопрос о том, подходит ли груз для перевозчика, может быть концепцией предметной области.

Возможно, вам потребуется проверить существование вещей, например. Существует ли бизнес или пользователь. Хотя эта проверка, скорее всего, потребует от вас доступа к базе данных, она все же поверхностна, поскольку вряд ли будет явной концепцией предметной области.

Во всяком случае, я надеюсь, что это поможет.

person Codescribler    schedule 22.06.2017

Здесь есть два основных аспекта:

  1. В CQRS у вас есть команды и запросы. Откуда берутся события? Предполагая, что вы также имеете в виду Event Sourcing, тем не менее, при использовании команд вы выполняете некоторую проверку на клиенте, некоторые в обработчике команд и некоторые внутри вашей модели предметной области (агрегированные инварианты и ограничения). Этот конкретный пример выглядит как что-то, что проверяется на клиенте и внутри обработчика команд.

  2. Помните, что, поскольку у вас есть три разные операции с тремя разными агрегатами, вам нужно иметь три транзакции. Это означает, что если один из них не завершится - ваша система придет в недопустимое состояние. Вам нужно либо пересмотреть границы агрегации, чтобы иметь один агрегированный корень, либо подумать об использовании других методов, таких как политики, управляемые событиями, саги (менеджеры процессов) или маршрутные промахи (саги).

Определенно, UserToBusinessRelationship больше похоже на таблицу ссылок RDBMS «многие ко многим», чем на совокупность, но я ничего не знаю о вашем домене.

person Alexey Zimarev    schedule 22.06.2017