Move validation into Form Requests
Validating inline with $request->validate() works fine until a controller method has to do it, authorize it, and handle the business logic all at once. A Form Request pulls the validation — and the authorization check — into its own class, so the controller only ever sees data that's already clean.
-
Generate the request
The
make:requestartisan command creates a class inapp/Http/Requestswith two methods already stubbed out:authorize()andrules().php artisan make:request StoreProductRequest -
Decide who's allowed to make this request
authorize()runs beforerules(). Returnfalseand Laravel aborts with a 403 before any validation happens — useful for checking a policy or a simple ownership rule without cluttering the controller.public function authorize(): bool { return $this->user()->can('create', Product::class); }Most of the time this can just
return true;and let a middleware or policy handle authorization elsewhere. -
Write the rules
rules()returns the same array shape as$request->validate()would take — see the next tutorial for everything that can go in here.public function rules(): array { return [ 'name' => 'required|string|max:255', 'price' => 'required|numeric|min:0', ]; } -
Type-hint it instead of Request
Swap the controller method's
Requesttype-hint for the Form Request class. Laravel resolves it out of the container, runsauthorize()andrules()automatically, and — on failure — redirects back with the errors flashed to the session for a normal web request, or returns a 422 JSON response for an API call. The controller method body never even runs if validation fails.use App\Http\Requests\StoreProductRequest; public function store(StoreProductRequest $request) { $product = Product::create($request->validated()); return redirect()->route('products.show', $product); } -
Use validated(), not all()
$request->validated()returns only the fields that were actually declared inrules()— so a request stuffed with extra fields can't sneak them into a mass-assignment call.$request->all()would include everything the client sent, validated or not.