Form Request - окремий клас для валідації й авторизації запиту. Контролер отримує вже перевірені дані.
php artisan make:request StoreOrderRequest
class StoreOrderRequest extends FormRequest
{
public function authorize(): bool
{
return $this->user()->can('create', Order::class);
}
public function rules(): array
{
return [
'items' => ['required', 'array', 'min:1', 'max:50'],
'items.*.product_id' => ['required', 'integer', Rule::exists('products', 'id')->where('active', true)],
'items.*.qty' => ['required', 'integer', 'between:1,100'],
'comment' => ['nullable', 'string', 'max:1000'],
];
}
}
public function store(StoreOrderRequest $request): JsonResponse
{
$order = $this->orders->create($request->user(), $request->validated());
return (new OrderResource($order))->response()->setStatusCode(201);
}
Що відбувається автоматично:
- Laravel створює запит і викликає
authorize()до контролера.false- відповідь403; rules()- валідація; помилки -422з полемerrors(для запитів зAccept: application/json);- контролер виконується лише якщо все пройшло.
Чому це краще за $request->validate() у контролері:
- контролер коротший і читається як бізнес-логіка;
- правила й авторизацію легко перевикористати (створення й оновлення часто ділять більшість правил);
$request->validated()- лише перевірені поля. Передавати їх уcreate()безпечно: зайве поле з тіла запиту (is_admin) туди не потрапить.
Корисні можливості:
prepareForValidation()- нормалізувати вхідні дані до перевірки (обрізати пробіли, привести телефон до одного формату);after()- перевірки, що охоплюють кілька полів або потребують бази;messages()іattributes()- власні тексти помилок і назви полів;$stopOnFirstFailure- зупинити валідацію на першій помилці.
Пастки API:
- межі масивів (
max:50) і рядків обов'язкові: клієнт може надіслати мегабайти даних; existsз умовами (where('active', true)) - інакше можна замовити неактивний чи чужий товар;sometimesдляPATCH: поле перевіряється, лише якщо прийшло, - часткове оновлення не вимагає всіх полів;- авторизація конкретного об'єкта (
$this->route('order')) вauthorize()- захист від доступу до чужих записів.