• Czas czytania ~4 min
  • 07.04.2023

Żądania formularzy są najbardziej znane z przenoszenia logiki sprawdzania poprawności z kontrolerów sieci Web do klasy, która będzie wstępnie sprawdzać poprawność. Są fantastyczne i cały czas mocno się na nich opieram. Co jeszcze możemy zrobić z prośbami o formularze?

Oprócz dodawania metod i wywoływania ich wewnątrz kontrolerów istnieje kilka metod często nieużywanych w żądaniach formularzy, na których można polegać, aby dodać dodatkowe superuprawnienia do aplikacji.

Przygotowywanie danych wejściowych do walidacji

Ta metoda jest fantastyczna, gdy musisz przekształcić lub dodać więcej do żądania przed uruchomieniem walidatora. Dokumenty pokazują przykład łączenia ślimaka z czymś, co jest pomocne, ale co powiesz na inny przykład?

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.

W tej metodzie moglibyśmy nawet dynamicznie zastępować treści.

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.

Walidacja

zaliczona Podobnie jak w przypadku przygotowań do walidacji, możemy korzystać z danych żądania po walidacji, standaryzować lub formatować dane żądania do określonego formatu. Jako ktoś, kto codziennie pracuje z danymi, jest to bardzo przydatne.

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.

Autoryzacja

nieudana Zazwyczaj gdy autoryzacja żądania formularza nie powiedzie się, struktura zgłosi AuthorizationExceptionplik . W przypadku 99% przypadków użycia jest to wszystko, czego potrzebujesz. Jest jednak kilka bardziej niejasnych momentów, kiedy chcesz uniknąć takiego wyjątku. Załóżmy, że przechwytujesz elementy webhook z interfejsu API innej firmy, a zgłoszenie wyjątku autoryzacji spowoduje dziwne, niekontrolowane zachowanie w tej stronie trzeciej. Zamiast tego można po cichu zakończyć się niepowodzeniem, zastępując tę metodę w żądaniu formularza.

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.

Spójrzmy na przykład kontrolera, który zazwyczaj mogę napisać:

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.

Ograniczenia tego, co możesz zrobić na żądaniach formularzy, są ograniczone tylko przez twoją wyobraźnię, ale upewnij się, że używasz ich mądrze. Nie są one po to, aby zastąpić logikę aplikacji, pamiętaj! Ważne jest, aby logika aplikacji była zawsze dostępna i czytelna i nie zaginęła w morzu logiki struktury lub walidacji żądań.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

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...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297