Powered by Smartsupp

Request Pattern v Laravelu

Request Pattern v Laravelu

Udržet controllery v Laravelu štíhlé je výzva, se kterou bojuje každý vývojář, jakmile projekt vyroste z malé ukázky na reálný produkt. Často končíme u metod, které validují data, transformují vstupy, řeší autorizaci a následně provádějí byznys logiku. Výsledkem je nepřehledný kód, který se špatně testuje a ještě hůře udržuje.

Request Pattern (v kombinaci s Form Requests) představuje první obrannou linii vaší architektury. Nejde jen o přesun validace jinam. Jde o vytvoření kontraktu mezi vstupními daty od uživatele a vaší aplikací. Cílem je zajistit, aby do servisní vrstvy nebo modelu doputovala pouze data, u kterých jsme si stoprocentně jistí jejich integritou.


Jak to vypadá, když se Request Pattern nepoužívá? (Anti-pattern)

V mnoha projektech se setkáte s tzv. "Fat Controllerem". Na první pohled se může zdát, že je vše v pořádku, protože kód funguje. Problém nastává ve chvíli, kdy potřebujete změnit validační pravidlo nebo přidat stejnou logiku pro mobilní aplikaci.

Podívejme se na odstrašující příklad metody v controlleru:

public function store(Request $request)
{
    // 1. Ruční validace přímo v metodě (nepřehledné)
    $request->validate([
        'title' => 'required|string|max:255',
        'content' => 'required|string',
        'category_id' => 'required|exists:categories,id',
    ]);

    // 2. Kontrola oprávnění (pokud zapomenete na middleware nebo Policy)
    if (!$request->user()->can('create-article')) {
        abort(403);
    }

    // 3. Nebezpečné ukládání dat přes all()
    $article = Article::create($request->all()); 

    return response()->json($article);
}

Proč je tento přístup špatně?

  • Kognitivní zátěž: Musíte číst desítky řádků, abyste zjistili, co metoda skutečně dělá.

  • Porušení SRP (Single Responsibility Principle): Controller validuje, autorizuje i ukládá.

  • Nemožnost znovupoužitelnosti: Validaci nemůžete snadno použít jinde (např. v API).

Varování: Skryté nebezpečí $request->all()

Používání $request->all() při ukládání dat je bezpečnostní riziko známé jako Mass Assignment. Pokud útočník pošle v requestu pole is_admin = true a vy ho slepě předáte do modelu, který nemá správně nastavený $fillable, může si kdokoli povýšit svá práva. Request Pattern vás nutí definovat přesně to, co do aplikace smí vstoupit.


Implementace pomocí Form Request

Laravel nabízí vestavěný způsob, jak oddělit validační logiku: Form Request. Místo obecné třídy Illuminate\Http\Request použijeme vlastní třídu.

Vytvoření Request třídy

Příkazem v terminálu vytvoříme novou třídu:

php artisan make:request StoreArticleRequest

Praktická ukázka se zapouzdřenou logikou

Sledujte, jak třída StoreArticleRequest přebírá zodpovědnost za čistotu dat:

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreArticleRequest extends FormRequest
{
    public function authorize(): bool
    {
        // Autorizace přímo spojená s tímto požadavkem
        return $this->user()->can('create', Article::class);
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'content' => ['required', 'string'],
            'category_id' => ['required', 'exists:categories,id'],
            'status' => ['required', 'in:draft,published'],
        ];
    }
}

Od Requestu k DTO: Vyšší úroveň architektury

Ačkoliv Form Request skvěle řeší validaci, stále se jedná o objekt vázaný na HTTP vrstvu. Pokud voláte logiku z CLI (Artisan příkazy) nebo Jobů, HTTP Request nemáte. Proto je nejlepším postupem transformovat Request na Data Transfer Object (DTO).

Příklad DTO implementace

Představme si jednoduchou třídu, která drží naše data:

readonly class ArticleData
{
    public function __construct(
        public string $title,
        public string $content,
        public int $categoryId,
        public string $status,
    ) {}

    public static function fromRequest(StoreArticleRequest $request): self
    {
        // Používáme POUZE validovaná data
        return new self(
            title: $request->validated('title'),
            content: $request->validated('content'),
            categoryId: (int) $request->validated('category_id'),
            status: $request->validated('status'),
        );
    }
}

Čistý Controller v praxi

Díky Request Patternu a DTO se náš controller smrskne na minimum. Stará se pouze o směrování toku.

public function store(StoreArticleRequest $request, CreateArticleAction $action)
{
    // Request je automaticky validován před vstupem do metody
    $article = $action->execute(
        ArticleData::fromRequest($request)
    );

    return response()->json($article, 201);
}

Shrnutí

Implementace Request Patternu v Laravelu není jen o tom "mít více souborů". Je to o striktním oddělení odpovědností.

  • Form Request se stará o autorizaci a validaci HTTP vstupu.

  • DTO přenáší data v typově bezpečné formě do hlubších vrstev aplikace.

  • Eliminace $request->all() chrání vaši databázi před neautorizovanými změnami.

Tímto přístupem eliminujete chyby vznikající z neočekávaných dat a výrazně zrychlíte vývoj, protože pravidla hry jsou jasně definována v dedikovaných třídách.

Chcete mít v týmu vývojáře, kteří píší takovýto kód? Spojte se s námi:
https://devboys.cz/kontakt

Co se stane po odeslání?

Jsme tu pro Vás

Vaši zprávu si přečtu přímo já nebo kolega z týmu. Do 24 hodin se vám ozveme zpět, abychom probrali detaily. Žádní obchodní zástupci, ale rovnou technická konzultace k věci, která vás posune dál.

Osobní přístup

Jednáte přímo s vývojáři, ne s account managery.

< 24 h reakční doba

Ozveme se rychle s jasnými dalšími kroky.

IČO 06109152
DIČ CZ9102040431 (Plátce DPH)
Společnost zapsaná v obch. rejstříku, vedeného MÚ Plzeň, spis. zn. 231/98.

Kontaktujte nás