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 poleis_admin = truea 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