Почему проверка данных - это многослойная система, а не единая функция
Сегодня поговорим о том, что скрывается за простым словом «валидация». Когда пользователь вводит email в форму, он проходит не одну, а целую цепочку проверок. Каждая на своем уровне, со своей логикой и своими последствиями. Понимание этой цепочки - основа проектирования надежных систем.
Единый термин, множество смыслов:
Кажется, что проверить email - это просто: есть символ «@», точка в домене, и все. Но в реальном приложении эта проверка повторяется несколько раз, становясь с каждым разом строже и затрагивая все более глубокие слои системы. И это не баг, а фича - принцип защиты в глубину.
Четыре уровня, одна цель:
Первый круг - удобство (Клиент):
Здесь все делается для человека. Поле подсвечивается красным, если нет символа «@». Кнопка «Отправить» неактивна, пока не заполнены обязательные поля. Это быстро, наглядно и бережет нервы пользователя. Но и только. Любой скрипт или даже просто вкладка DevTools может отправить что угодно, минуя эти проверки. Полная безопасность здесь невозможна в принципе.
Второй круг - формат (Вход в API):
Запрос дошел до сервера. Первым его встречает не бизнес-логика, а механизм проверки структуры. Используются инструменты вроде Pydantic или валидаторы, сгенерированные из OpenAPI-спецификации.
Задача - отсечь явный мусор. Пришел ли валидный JSON? Соответствует ли он ожидаемой схеме? Есть ли в объекте поле email и является ли оно строкой?
Если здесь ошибка - сервер отвечает 400 Bad Request. Это сигнал: «Я даже не стал разбираться в твоей бизнес-логике, потому что запрос кривой». Уровень не проверяет, свободен ли email, только его формальную пригодность.
Третий круг - смысл (Бизнес-правила):
Данные правильного формата попадают в сердце приложения. Здесь живут правила, которые делают систему уникальной. Для email это может быть проверка домена (не принимаем с @example.com), проверка по списку стоп-слов или, что важно, запрос к другому сервису или базе данных на предмет существования такой учетной записи.
Именно здесь обычно выполняется тот самый запрос «существует ли уже этот email?». Это не валидация формата, а полноценная бизнес-операция.
Если правило нарушено, стандартный ответ: 422 Unprocessable Entity. Сообщение: «Запрос понятен и формально корректен, но мы не можем его выполнить по внутренним правилам».
Четвертый круг - гарантия (База данных):
Это последний рубеж, железобетонный. Даже если все предыдущие уровни по какой-то причине (баг, прямое вмешательство в БД) пропустили дубликат, база данных его не пропустит, если на столбце стоит UNIQUE CONSTRAINT. Это защита от рассинхронизации, конкурирующих запросов и человеческих ошибок.
Нарушение здесь - это уже серьезный инцидент, часто ведущий к 500 Internal Server Error, потому что система столкнулась с невозможным с точки зрения ее фундаментальных правил.
Вывод:
Главный вывод - валидация должна быть слоистой. Это не куча случайных проверок в одном месте, а четкая иерархия, где каждый следующий слой строже предыдущего и страхует его.
Клиент проверяет для удобства, фреймворк - для отсева мусора, бизнес-логика - для соблюдения правил, база данных - для абсолютной гарантии. Код ответа (400, 422, 500) - это не просто номер, а точный сигнал о том, на каком именно этапе путешествия данные споткнулись.
Проектируя так, вы создаете не только безопасную, но и понятную систему, где причина любой ошибки очевидна из того, где и как она возникла.
20.01.2026 7 254