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);
}