CQRS. Как выводить созданную запись?

Обсуждаем, как правильно строить приложения
Ответить
myks1992@mail.ru
Сообщения: 137
Зарегистрирован: 2017.11.15, 23:54

CQRS. Как выводить созданную запись?

Сообщение myks1992@mail.ru » 2019.07.30, 18:36

Всем привет. Есть вопрос-уточнение по паттерну CQRS. Надеюсь на вашу помощь. В нём сказано, что команда не должна ничего отдавать. Команда должна только выполнять. Однако бывают ситуации, когда нам, например, при создании сущности и сохранения его в базе, необходимо сделать редирект на созданную запись.

Для создания записи в базе мы посылаем команду UserCreateConmand, которая вызывает обработчик UserCreateHandler с методом handle. Однако, в таком случае, созданная командой сущность, по всем правилам паттерна, не должна ничего возвращать. То есть работать асинхронно. Тогда возникает вопрос как нам получать данные созданной записи (ID), для перенаправления на неё после создания (синхронно)? Чтобы можно было вызвать ['user/view', 'id' => ID]

Ещё хотел спросить про ViewModel. Не подскажете как может выглядеть эта модель для Index страницы. Там же получается будет массив, и пиганация, но как правильно с ним работать не понимаю...

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: CQRS. Как выводить созданную запись?

Сообщение samdark » 2019.07.30, 18:46

В этом паттерне ID получаются из sequence, внешнего источника или используется UUID. Автоинкремент с ним не работает.

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: CQRS. Как выводить созданную запись?

Сообщение samdark » 2019.07.30, 18:47

ViewModel — это просто класс, который содержит всю логику отображения кроме собственно шаблона.

myks1992@mail.ru
Сообщения: 137
Зарегистрирован: 2017.11.15, 23:54

Re: CQRS. Как выводить созданную запись?

Сообщение myks1992@mail.ru » 2019.07.30, 19:53

samdark писал(а):
2019.07.30, 18:46
В этом паттерне ID получаются из sequence, внешнего источника или используется UUID. Автоинкремент с ним не работает.
Благодарю за помощь! Теперь понял. А то не знал как с автоинкрементном применять такой паттерн и ломал голову)

myks1992@mail.ru
Сообщения: 137
Зарегистрирован: 2017.11.15, 23:54

Re: CQRS. Как выводить созданную запись?

Сообщение myks1992@mail.ru » 2019.07.30, 19:55

samdark писал(а):
2019.07.30, 18:47
ViewModel — это просто класс, который содержит всю логику отображения кроме собственно шаблона.
Да, это понял. Кстати, хорошо бы было его сделать в GII генераторе ViewModel вместо работы доменной сущности, раз уж в Yii3 так сильно решили подойти к архитектуре. Мне такое использование больше нравится чем использование хэлперов.

Аватара пользователя
samdark
Администратор
Сообщения: 9201
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: CQRS. Как выводить созданную запись?

Сообщение samdark » 2019.07.31, 00:38

Одно другому не мешает.

anton_z
Сообщения: 440
Зарегистрирован: 2017.01.15, 15:01

Re: CQRS. Как выводить созданную запись?

Сообщение anton_z » 2019.07.31, 02:37

myks1992@mail.ru писал(а):
2019.07.30, 18:36

Для создания записи в базе мы посылаем команду UserCreateConmand, которая вызывает обработчик UserCreateHandler с методом handle. Однако, в таком случае, созданная командой сущность, по всем правилам паттерна, не должна ничего возвращать. То есть работать асинхронно.

Однако бывают ситуации, когда нам, например, при создании сущности и сохранения его в базе, необходимо сделать редирект на созданную запись.
Асинхроность и редирект после создания по UUID плохое решение. Если у вас команда выполняется асинхронно, где гарантия, что она выполнится раньше, чем произойдет редирект? Гарантий никаких тут быть не может.

Если уж делать асинхронный CQRS (надеюсь, есть веское основание), я бы делал так - команде при отправке в асихронную шину команд присваивается идентификатор команды. Он должен быть/стать известен коду, который отправил команду. Далее до редиректа нужно где-то проверять статус выполнения отправленой команды и только после успешного выполнения делать редирект. Вот тогда получится норм решение с CQRS. В общем, до редиректа, то есть фактически, отображения результата выполнения асинхронной операции пользователю, нужно убедиться в том что операция действительно выполнилась.

myks1992@mail.ru
Сообщения: 137
Зарегистрирован: 2017.11.15, 23:54

Re: CQRS. Как выводить созданную запись?

Сообщение myks1992@mail.ru » 2019.07.31, 02:48

anton_z писал(а):
2019.07.31, 02:37
myks1992@mail.ru писал(а):
2019.07.30, 18:36

Для создания записи в базе мы посылаем команду UserCreateConmand, которая вызывает обработчик UserCreateHandler с методом handle. Однако, в таком случае, созданная командой сущность, по всем правилам паттерна, не должна ничего возвращать. То есть работать асинхронно.

Однако бывают ситуации, когда нам, например, при создании сущности и сохранения его в базе, необходимо сделать редирект на созданную запись.
Асинхроность и редирект после создания по UUID плохое решение. Если у вас команда выполняется асинхронно, где гарантия, что она выполнится раньше, чем произойдет редирект? Гарантий никаких тут быть не может.

Если уж делать асинхронный CQRS (надеюсь, есть веское основание), я бы делал так - команде при отправке в асихронную шину команд присваивается идентификатор команды. Он должен быть/стать известен коду, который отправил команду. Далее до редиректа нужно где-то проверять статус выполнения отправленой команды и только после успешного выполнения делать редирект. Вот тогда получится норм решение с CQRS. В общем, до редиректа, то есть фактически, отображения результата выполнения асинхронной операции пользователю, нужно убедиться в том что операция действиетльно выполнилась.
Всё правильно говорите) Пока что CQRS у меня получился синхронный. И я могу позволить себе решение с UUID, однако про асинхронность тоже хорошо понимать на будущее. Особенно если консистенция данных не сходится, чтобы запустить на Query команду.

Могли бы вы кратко показать использование асинхронной работы. Куда передавать ID команды и откуда получать? Это диспечер? Либо скинуть на статью.

Ответить