Senior: питання на співбесіді з теми «Валідація»
Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.
2 питання
Правило unique - це SELECT перед вставкою. Між перевіркою й записом інший запит встигає вставити той самий email.
Запит A: SELECT ... email = 'a@x.com' -> немає
Запит B: SELECT ... email = 'a@x.com' -> немає
Запит A: INSERT a@x.com -> ок
Запит B: INSERT a@x.com -> дубль
Що робити:
- Унікальний індекс у базі - єдина справжня гарантія. Валідація лишається для зрозумілого повідомлення в нормальному випадку.
- Обробити порушення індексу - Laravel кидає
UniqueConstraintViolationException, його перетворюють на ту саму помилку валідації. АбоcreateOrFirst(), який робить це сам.
try {
$user = User::create($data);
} catch (UniqueConstraintViolationException) {
throw ValidationException::withMessages(['email' => __('validation.unique', ['attribute' => 'email'])]);
}
Деталі правила, про які питають:
- при оновленні виключають поточний запис:
Rule::unique('users')->ignore($user->id);ignore()ніколи не беруть з даних запиту - лише з моделі, інакше клієнт підставить чужий ID; withoutTrashed()не враховує м'яко видалені записи;- регістр:
Ada@x.comіada@x.comрізні дляunique, тож email нормалізують до нижнього регістру ще до валідації.
Для API валідація - це контракт: клієнти парсять помилки програмно, тож формат і поведінка мають бути передбачуваними.
Що Laravel дає з коробки: якщо запит очікує JSON (Accept: application/json), замість перенаправлення повертається 422:
{
"message": "The email field is required. (and 1 more error)",
"errors": {
"email": ["The email field is required."],
"items.0.quantity": ["The items.0.quantity field must be at least 1."]
}
}
Вкладені ключі сплющуються в «крапкову» нотацію.
Що варто налаштувати:
- Невідомі поля.
#[FailOnUnknownFields]на запиті форми (або глобальноFormRequest::failOnUnknownFields()) відхиляє поля, яких немає в правилах. Помилки клієнта на кшталтemialстають помітними одразу, а не тихо ігноруються. - Стабільні повідомлення. Клієнти не мають залежати від тексту - лише від ключів полів і HTTP-коду. Якщо потрібні машинні коди помилок, їх додають власним форматом відповіді.
- Межі вхідних даних:
maxдля рядків і масивів, ліміт розміру тіла запиту на вебсервері. - Мова повідомлень за заголовком
Accept-Language, якщо API багатомовний.
Тести: assertUnprocessable() і assertInvalid([...])/assertJsonValidationErrors() фіксують контракт, щоб зміна правил не зламала клієнтів непомітно.
Докладніше в документації: Формат відповіді з помилками валідації