Валидация ввода для API

Добавление предварительной валидации данных команд для красивого отображения ошибок в формате JSON для отображения на фронтенде. Централизованный вывод ошибок валидации в middleware.

Скрытый контент
Комментарии (12)
Denis

Добрый день, спасибо за урок. А будет как - то реализованы коды ошибок? Чтобы фронт знал как необходимо реагировать на ту или иную ошибку.

Ответить
Дмитрий Елисеев

Пока все ошибки у нас либо доменные, либо валидации. Для кастомного кода можно возвращать напрямую $exception->getCode().

Ответить
Дмитрий

Дмитрий здравствуйте, не могу понять как работает

/**
 * @Assert\NotBlank
 */

Как вообще могут комментарии влиять на код? Здесь получается мы вызвали метод NotBlank? Как это вообще работает?

Ответить
Дмитрий Елисеев

Непосредственно в PHP это просто комментарии и нативно они никак не работают..

Валидатор использует библиотеку doctrine/annotations. А она уже просто обходит поля через рефлексию и парсит эти строки.

Ответить
Arunas

Спасибо. Очень интересно.

Ответить
Роман

Дмитрий, после коммита Extracted validation handling ElisDN, psalm стал ругаться на ошибку ERROR: UndefinedDocblockClass в ValidationExceptionHandler::errorsArray на строку $violation->getMessage(). Решил путём установки полифилла composer require symfony/polyfill-php80 --dev чтобы был доступен \Stringable интерфейс

Ответить
Дмитрий Елисеев

Да, в свежем валидаторе на будущее добавили Stringable, который появится только в PHP 8.0.

Ответить
Евгений

Как поступить в случае, если формат запроса не совпадает с форматом команды? Тогда сообщения об ошибках валидации будут кодироваться неправильными полями. И пользователю будет непонятно к какому полю относится ошибка.

Ответить
Дмитрий Елисеев

В случае если пользователь пришлёт в email вместо строки массив? Тогда да, вылетит ошибка типов. Можно либо добавить приведение (string)($data['email'] ?? ''), либо воспользоваться сериализатором вроде symfony/serializer и отлавливать его исключения.

Ответить
Евгений

Нет. Я имел в виду разные названия полей. У меня недавно был случай когда нужно было к одной команде интегрировать два клиента, но переписать их я не мог. В итоге один присылал email в поле "email", а второй в виде "clientEmail". Если валидацию сделать на уровне команды, то второму клиенту уйдёт сообщение, что email неверный, а он ожидает clientEmail. В итоге я сделал объект формы для валидации ввода с фабричным методом создания команды. Но таким образом оставил команду без валидации. После этого видео задумался, что это не правильно.

Ответить
Евгений

Дмитрий, вы привели пример с валидацией email в объекте Email и поля email в команде. Валидатор email практически стандартный. Но что если нужен кастомный валидатор? Получается его логику придётся дублировать в инициализации объекта/типа и в проверке правильности команды. Подозреваю, что если возникнет ещё один слой с DTO, то придётся и там проверять ещё раз. Например перед записью в хранилище. Но это слабый пример, так как мы доверяем нашей модели.

Ответить
Дмитрий Елисеев

Если сложный кастомный, то да, либо дублировать, либо оставить только в одном месте.

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий