RSS Telegram YouTube Apple Яндекс Spotify Google Amazon Почта

12. Валидация

12.08.2023

Скачать

К списку выпусков

🔬 Валидация, верификация, RFC7807 и Марк Нотингем, анмаршалер JSON в Go и его связь с точностью валидации и как сообщать пользователю об ошибках.

Валидация данных — это их проверка на соответствие установленным критериям. Валидные данные могут использоваться, но при этом могут быть неточными или ошибочными. Точность данных проверяется через верификацию. Например, когда сайт присылает письмо со ссылкой для подтверждения адреса электронной почты или когда пользователь повторно вводит пароль для его подтверждения.

При создании веб-сервиса я обычно прописываю требования к данным с помощью документации OpenAPI. Под "данными" я подразумеваю не только содержимое запроса, но и его заголовки и начальную строку (при использовании HTTP/1.1).

Часто нам приходится работать с текстом в формате JSON, который мы конвертируем в структуру Go. Можно преобразовать текст в словарь, но потом, вероятно, придется провести проверку типов. При конвертации в структуру пакет json автоматически проводит эту проверку, делая код более чистым.

Десериализация текста в структуру имеет свои нюансы. Чтобы предоставлять корректные сообщения об ошибках, необходимо учитывать эти особенности. Качественное сообщение об ошибке должно указывать, где возникла проблема, какое значение было получено и какое правило нарушено. Это избавляет от необходимости просматривать документацию API и искать переданные данные в логах.

Понимание работы с JSON в Go позволяет предоставлять точные и понятные сообщения об ошибках.

Представьте структуру в Го с полем Age (int), которое по документации является обязательным и должно быть не меньше 1. После десериализации данных, у вас стоит Age = 0. Но можно ли исходя из этой структуры точно сказать, как выглядел исходный JSON?

Оказывается, нет. Клиент мог отправить разные JSON объекты, что делает структуру Го не всегда точным отражением JSON. Сценарии могут быть таковыми: клиент передал 0; клиент передал null; клиент ничего не передал.

Какую ошибку чаще всего возвращают в таком случае? Многие бы просто указали, что передача значения 0 недопустима и минимальное значение - 1. Но что, если клиент на самом деле передал null или просто пропустил это поле? Такое сообщение об ошибке может ввести в заблуждение разработчика.

В идеале сообщения об ошибках должны быть более конкретными: если передан null — укажите на это; если поле пропущено, но обязательно — сообщите об этом клиенту.

Ранее я создал кастомные типы данных с методом UnmarshallJSON для более точного определения ошибок. Эти типы включали в себя структуры с флагами, показывающими, передали ли поле или отправили null, а также значение поля. Этот подход потребовал создания множества типов и функций, превратив мой код в мини-фреймворк.

Однако, со временем я осознал, что цена за точность сообщений об ошибках слишком высока. Мой код стал менее читаемым из-за избытка селекторов и добавленной сложности, что делало его менее продуктивным. Более того, такая детализация делала логи труднодоступными для чтения.

К списку выпусков