Form Request перевіряється ще до виклику методу контролера - коли контейнер створює його як аргумент. Порядок кроків:
authorize()-falseчи заборонена відповідь політики →AuthorizationException→ 403. Якщо методу немає, запит вважається дозволеним;prepareForValidation()- підготувати дані (нормалізувати, об'єднати);rules()+ валідатор, разом зafter()- додаткові перевірки після основних правил;- при помилці -
failedValidation(): редирект назад з помилками чи 422 для JSON; - при успіху -
passedValidation(), і лише потім виконується контролер.
after() - перевірки, яким потрібні вже провалідовані значення чи кілька полів одразу:
public function after(): array
{
return [
function (Validator $validator) {
if ($this->date('ends_at') <= $this->date('starts_at')) {
$validator->errors()->add('ends_at', 'Кінець має бути пізніше за початок.');
}
},
new EnsureSlotIsFree, // клас з __invoke(Validator $validator)
];
}
Налаштування поведінки - властивостями чи, у Laravel 13, атрибутами класу:
#[StopOnFirstFailure] // зупинитися на першому полі з помилкою
#[RedirectToRoute('checkout.show')] // куди повертати замість back()
#[ErrorBag('checkout')] // окремий мішок помилок для кількох форм на сторінці
#[FailOnUnknownFields] // помилка на полях, яких немає в rules()
final class CheckoutRequest extends FormRequest { /* ... */ }
FailOnUnknownFields - новинка Laravel 13: якщо клієнт надіслав поле, якого немає в rules(), кожне таке поле отримує помилку prohibited. Захищає від масового присвоєння й опечаток у назвах полів на фронтенді. Глобально - FormRequest::failOnUnknownFields() у сервіс-провайдері.
Власна реакція на помилку - перевизначити failedValidation():
protected function failedValidation(Validator $validator): void
{
throw new HttpResponseException(response()->json([
'title' => 'Validation failed',
'errors' => $validator->errors(),
], 422));
}
Для API це зазвичай краще зробити один раз у bootstrap/app.php для всіх запитів, а не в кожному класі.
Що пам'ятати:
authorize()не замінює політик: вона виконується до валідації, тож дані запиту ще не перевірені - звертатися до них обережно;validated()іsafe()повертають лише перевірені поля - саме їх передають у модель, а неall();after()виконується навіть після помилок основних правил - перевірки в ньому мають враховувати, що поля можуть бути порожніми чи некоректними.
Докладніше в документації: Валідація: додаткова перевірка у Form Request