API & Architecture

Mastering Form Requests & Validation Architecture

Senior Editor
Oct 1, 2026
7 min read

Keep controllers pristine by moving complex input validation, authorization rules, and sanitized data casting into dedicated Form Request classes.

Why Separate Validation from Controllers?

When controllers perform $request->validate([...]) directly, validation logic duplicates across endpoints, controller methods grow unwieldy, and testing validation error branches requires clumsy HTTP simulation.

Form Requests encapsulate authorization and input validation into dedicated classes.

PHP
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreProjectRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('create', Project::class);
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string', 'max:5000'],
            'status' => ['required', 'in:draft,active,completed'],
        ];
    }
}

Type-Safe Data Retrieval

Always access validated input with $request->validated() instead of the untrusted $request->all():

PHP
public function store(StoreProjectRequest $request, CreateProjectAction $action)
{
    $project = $action->execute($request->user(), $request->validated());

    return redirect()->route('projects.show', $project);
}
Topics in this article

Author

Senior Editor

Core Contributor

Related Knowledge Articles

Transform bloated controllers and fragmented services into single-responsibility Action classes that are clean, testable, and reusable.
Prevent path traversal, MIME spoofing, and unauthorized download exposure when serving learning resources.
Implement fine-grained resource authorization using Laravel Policies, Gate definitions, and Inertia authorization props.