Laravel Tutorial · Requests and Responses · Lesson 9 of 27

Laravel Validation

Validate input with rules like required, email, min and unique; get automatic 422 JSON errors; and move complex rules into Form Request classes.

Create a free account to save this page, take notes and track your progress. Sign in

Validating a request

$request->validate([...]) checks the input against rules and returns only the validated data. If validation fails:

  • for JSON/API requests, Laravel answers 422 with an errors object listing every failed field,
  • for HTML forms, it redirects back with the errors and old input (shown with @error in Blade).

Rules can be strings ('required|email|max:255') or arrays. Common ones: required, nullable, string, integer, numeric, boolean, email, url, min, max, between, in:a,b, confirmed, date, after:today, unique:users,email, exists:categories,id, array, and items.*.qty for each element of an array.

Validation rules and 422 errors
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('/signup', function (Request $request) {
    $data = $request->validate([
        'name' => 'required|string|min:2|max:50',
        'email' => 'required|email',
        'age' => 'nullable|integer|min:13',
        'plan' => 'required|in:free,pro',
        'password' => 'required|min:8|confirmed',    // needs a matching password_confirmation field
    ]);
    return response()->json(['welcome' => $data['name'], 'fields' => array_keys($data)], 201);
});

visit('POST', '/signup', ['name' => 'Ana', 'email' => '[email protected]', 'plan' => 'pro',
    'password' => 'correct-horse', 'password_confirmation' => 'correct-horse', 'is_admin' => true]);
visit('POST', '/signup', ['name' => 'A', 'email' => 'not-an-email', 'age' => 9, 'plan' => 'gold',
    'password' => 'short', 'password_confirmation' => 'different']);

Output

POST /signup -> 201 {"welcome":"Ana","fields":["name","email","plan","password"]}
POST /signup -> 422 {"message":"The name field must be at least 2 characters. (and 5 more errors)","errors":{"name":["The name field must be at least 2 characters."],"email":["The email field must be a valid email address."],"age":["The age field must be at least 13."],"plan":["The selected plan is invalid."],"password":["The password field must be at least 8 characters.","The password field confirmation does not match."]}}

Run this on your computer — see “Get Started” for setup.

Form Request classes

For bigger forms, create a Form Request (php artisan make:request StoreUserRequest) with rules(), optional messages() and authorize(). Type-hint it in the controller and validation runs before your method is called.

A Form Request with array rules and custom messages
<?php
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Route;

class StoreOrderRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;   // e.g. return $this->user()->can('order');
    }

    public function rules(): array
    {
        return [
            'items' => 'required|array|min:1',
            'items.*.sku' => 'required|string',
            'items.*.qty' => 'required|integer|between:1,10',
            'note' => 'nullable|string|max:200',
        ];
    }

    public function messages(): array
    {
        return ['items.*.qty.between' => 'Each quantity must be between 1 and 10.'];
    }
}

Route::post('/orders', fn (StoreOrderRequest $request) => ['accepted' => count($request->validated('items'))]);

visit('POST', '/orders', ['items' => [['sku' => 'MUG', 'qty' => 2], ['sku' => 'TEA', 'qty' => 1]]]);
visit('POST', '/orders', ['items' => [['sku' => 'MUG', 'qty' => 50]]]);
visit('POST', '/orders', []);

Output

POST /orders -> 200 {"accepted":2}
POST /orders -> 422 {"message":"Each quantity must be between 1 and 10.","errors":{"items.0.qty":["Each quantity must be between 1 and 10."]}}
POST /orders -> 422 {"message":"The items field is required.","errors":{"items":["The items field is required."]}}

Run this on your computer — see “Get Started” for setup.

Test yourself

What does $request->validate() return when validation passes?

  1. true
  2. The whole request
  3. Only the validated fields
  4. A Validator object
Show answer

Answer: Only the validated fields

Was this page helpful?