CommandBus и контроллеры Yii

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
belka3000
Сообщения: 16
Зарегистрирован: 2015.01.29, 14:52

CommandBus и контроллеры Yii

Сообщение belka3000 »

Народ вопрос такой, использую CommandBus - хочу внедрить в свои уиишные контроллеры.
Но вот если следовать паттерну шина ничего не должна возвращать, только кидать эксепшены.

Тогда как делать валидацию используя Yii-шные формы?

Вот допустим форма контактов:

Код: Выделить всё

 public function actionContact()
    {
        $command = new ContactSendCommand();
        $command->name = Yii::$app->request->post('ContactForm')['name'];
        $command->email = Yii::$app->request->post('ContactForm')['email'];
        $command->subject = Yii::$app->request->post('ContactForm')['subject'];
        $command->body = Yii::$app->request->post('ContactForm')['body'];
        $command->isRequested = Yii::$app->request->isPost;

        $contactModel = Yii::$app->commandBus->handle($command);

        if ($contactModel->isSuccess) {
            Yii::$app->session->setFlash('contactFormSubmitted');

            return $this->refresh();
        }

        return $this->render('contact', ['contactForm'=>$contactModel]);
    }
Смотрится ужасно.. т.к валидация должна идти на уровне команд, но отказываться от форм не хочется..
Кто как делает?
Аватара пользователя
SiZE
Сообщения: 2813
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: CommandBus и контроллеры Yii

Сообщение SiZE »

Передавать в шину валидную форму. Я думаю шина не должна заморачиваться валидацией, она выполняет команду.
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: CommandBus и контроллеры Yii

Сообщение zelenin »

можно валидировать извне, как выше предложили.

Но на самом деле шина не будет возвращать только если она что-то асинхронно делает.

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

выглядит так:

Код: Выделить всё

    /**
     * @param ServerRequestInterface $request
     * @param DelegateInterface $delegate
     *
     * @return ResponseInterface
     */
    public function process(ServerRequestInterface $request, DelegateInterface $delegate): ResponseInterface
    {
        $phoneId = $request->getAttribute('id');
        if (!$phoneId) {
            return new NotFoundResponse();
        }

        $body = $request->getParsedBody();

        $command = new ChangeStatus($phoneId, (int)$body->data->status_id);

        try {
            $context = $this->commandBus->handle($command);

            $validationResult = $context->value(ChangeStatusHandler::CONTEXT_VALIDATION_RESULT);

            if (!$validationResult) {
                return new NotValidatedResponse();
            }

            if (!$validationResult->isValid()) {
                return new ValidationErrorResponse($validationResult);
            }

            return new DataResponse([]);
        } catch (NotFound $e) {
            return new NotFoundResponse();
        }
    }
belka3000
Сообщения: 16
Зарегистрирован: 2015.01.29, 14:52

Re: CommandBus и контроллеры Yii

Сообщение belka3000 »

имеете в виду что шина возвращает контекст?
И вы потом что нужно выдергиваете?

Да, похоже придется форму сеттить и валидировать до шины и в шину уже отдавать отвалидированную от формы команду

Код: Выделить всё

public function actionContact()
{
        $contactModel = new ContactForm();

        if ($contactModel->load(Yii::$app->request->post()) && $contactModel->validate()) {
            $command = new ContactSendCommand();
            $command->name = $contactModel->name;
            $command->email = $contactModel->email;
            $command->subject = $contactModel->subject;
            $command->body = $contactModel->body;

            Yii::$app->commandBus->handle($command);

            Yii::$app->session->setFlash('contactFormSubmitted');

            return $this->refresh();

        }

        return $this->render('contact', ['contactForm' => $contactModel]);
}
zelenin
Сообщения: 10596
Зарегистрирован: 2013.04.20, 11:30

Re: CommandBus и контроллеры Yii

Сообщение zelenin »

belka3000 писал(а): 2017.05.19, 17:10 имеете в виду что шина возвращает контекст?
И вы потом что нужно выдергиваете?
да
belka3000 писал(а): 2017.05.19, 17:10 Да, похоже придется форму сеттить и валидировать до шины и в шину уже отдавать отвалидированную от формы команду

Код: Выделить всё

public function actionContact()
{
        $contactModel = new ContactForm();

        if ($contactModel->load(Yii::$app->request->post()) && $contactModel->validate()) {
            $command = new ContactSendCommand();
            $command->name = $contactModel->name;
            $command->email = $contactModel->email;
            $command->subject = $contactModel->subject;
            $command->body = $contactModel->body;

            Yii::$app->commandBus->handle($command);

            Yii::$app->session->setFlash('contactFormSubmitted');

            return $this->refresh();

        }

        return $this->render('contact', ['contactForm' => $contactModel]);
}
можно и так
Ответить