SyntaxStudy
Sign Up
Laravel Form Requests and Validation
Laravel Beginner 1 min read

Form Requests and Validation

Form requests are dedicated classes that encapsulate both authorization and validation logic for an HTTP request. When you type-hint a form request in a controller method, Laravel automatically runs authorization and validation before the method body executes. If validation fails, the user is redirected back with error messages stored in the session. If authorization fails, a 403 response is returned. The rules() method returns an array of validation rules using Laravel's extensive rule set: required, string, email, max, unique, exists, confirmed, and many more. Rules can be combined with pipe syntax ('required|email|max:255') or array syntax (an array of rule strings). Complex conditional rules, custom rule objects, and closure-based rules are also supported. Custom error messages are returned by overriding the messages() method, while custom attribute names for cleaner error display are returned from attributes(). The after() method lets you add additional validation logic that runs after all rules pass, such as business-rule checks that require querying the database or checking compound conditions.
Example
<?php
// app/Http/Requests/StorePostRequest.php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class StorePostRequest extends FormRequest
{
    public function authorize(): bool
    {
        // Only authenticated users may create posts
        return $this->user() !== null;
    }

    public function rules(): array
    {
        return [
            'title'      => ['required', 'string', 'max:255'],
            'slug'       => ['required', 'string', 'max:255', Rule::unique('posts')],
            'body'       => ['required', 'string', 'min:50'],
            'status'     => ['required', Rule::in(['draft', 'published'])],
            'category_id'=> ['required', 'integer', 'exists:categories,id'],
            'tags'       => ['nullable', 'array'],
            'tags.*'     => ['string', 'max:50'],
            'published_at'=> ['nullable', 'date', 'after_or_equal:today'],
        ];
    }

    public function messages(): array
    {
        return [
            'body.min' => 'The post body must be at least 50 characters.',
        ];
    }

    public function attributes(): array
    {
        return [
            'category_id' => 'category',
            'published_at' => 'publish date',
        ];
    }
}