• Время чтения ~2 мин
  • 07.04.2023

Запросы форм наиболее известны тем, что перемещают логику проверки из веб-контроллеров в класс, который будет предварительно проверяться. Они фантастические, и я все время сильно на них опираюсь. Что еще мы можем сделать с запросами форм?

Помимо добавления методов и вызова их внутри контроллеров, есть несколько методов, часто не используемых в запросах форм, на которые можно опереться, чтобы добавить дополнительные сверхспособности в приложение.

Подготовка входных данных к проверке

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

protected function prepareForValidation(): void
{
    $this->merge([
        'locale' => $this->user()->locale,
    ]);
}

We are merging the authenticated users' locale into the request - so we may perform dynamic validation based on the users' locale. Let's say we have limits in place in our application right now, which means that users from Wales (where I live) must add things in a specific format. Random, but I have seen a few use cases as a developer where this might have been useful.

Мы могли бы даже динамически заменять контент в этом методе.

protected function prepareInputForValidation(): void
{
    $replace = match ($this->user()->locale) {
        'en_GB' => 17.5,
        'en_US' => 10.0,
        'de_DE' => 12.5,
    };
    $this->replace([
        'tax_percentage' => $replace,
    ]);
}

Here, we dynamically change the tax percentage based on the users' locale. This is useful if you have specific tax rates as part of your import tax as a distributor.

Как и при подготовке к проверке, мы можем использовать данные запроса после проверки, стандартизировать или форматировать данные запроса в определенном формате. Как человек, который ежедневно работает с данными, это очень полезно.

protected function passedValidation(): void
{
    $this->replace([
        'name' => Str::uppercase($this->name),
    ]);
}

Again, these are not the most useful examples - but there is a lot you could do if you wanted, from turning properties into Value Objects for working with money to checking the content for spam.

Неудачная авторизация

Обычно, когда запрос формы не проходит авторизацию, платформа выдает . AuthorizationException Для 99% случаев использования это все, что вам нужно. Тем не менее, есть еще несколько неясных случаев, когда вы хотите избежать создания такого исключения. Предположим, вы захватываете веб-перехватчики из стороннего API, и создание исключения авторизации создаст странное, неконтролируемое поведение у этой третьей стороны. Вместо этого вы можете завершиться тихим сбоем, переопределив этот метод в запросе формы.

protected function failedAuthorization(): void
{
    Log::info('Failed authorization for webhook capture ....');
}

These are just a handful of the methods available on a Form Request, not to mention all those available using Laravel Precognition. But as I mentioned earlier, we can add our methods - allowing us to extend the functionality of our Form Requests a little more. A perfect example is the Laravel Breeze source code, where an authenticate method is added to the LoginRequest so the controller code can be simplified further.

Давайте рассмотрим пример контроллера, который я обычно пишу:

final class StoreController
{
    public function __construct(
        private readonly StoreCommand $command,
    ) {}
    public function __invoke(StoreRequest $request): Responsable
    {
        try {
            $this->command->handle(
                instance: new Instance(
                    name: $request->string('name')->toString(),
                ),
            );
        } catch (Throwable $exception) {
            throw new FailedToCreateInstance(
                message: 'Failed to create a new instance.',
                previous: $exception,
            );
        }
        return new CreatedResponse();
    }
}

This is a simplified controller where I use a creative class to send through a Data Object to keep my code consistent and clean how I like it. We can simplify our code more by leaning on our form request.

final class StoreController
{
    public function __construct(
        private readonly StoreCommand $command,
    ) {}
    public function __invoke(StoreRequest $request): Responsable
    {
        try {
            $this->command->handle(
                instance: $request->dto(),
            );
        } catch (Throwable $exception) {
            throw new FailedToCreateInstance(
                message: 'Failed to create a new instance.',
                previous: $exception,
            );
        }
        return new CreatedResponse();
    }
}

This looks similar, but imagine we are building something ten times more complex with many more request fields that we need to map to our data object - our controller will get big and messy in no time. All we have done here is move the creation of our Data Object to a method on the form request - nothing technical at all.

Ограничения того, что вы можете делать с запросами форм, ограничены только вашим воображением, но убедитесь, что вы используете их с умом. Они там не для того, чтобы заменить логику вашего приложения, помните! Важно убедиться, что логика приложения всегда доступна и читаема и не теряется в море логики платформы или проверки запросов.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Об авторе CrazyBoy49z
WORK EXPERIENCE
Контакты
Ukraine, Lutsk
+380979856297