Pull to refresh

Comments 6

Всё так. И это удивительно: trafaret, написанный на python, почти догоняет pydantic, который на rust. При этом первый ещё и выпускает по одному обновлению в год, а второй релизится раза по два каждый месяц

Учитывая, что вряд ли временные затраты на валидацию являются хоть сколько-нибудь весомыми на фоне бизнес-логики и всяких IO-операций, то можно делать выбор библиотеки не по скорости, а по удобству использования

По сути это не столько валидация, сколько парсинг — просто проверка того, что клиент прислал не совсем откровенный мусор. В реальности к этому добавляются примерно такие штуки, не рассмотренные в посте:

  • «email уже используется» или «выбранный объект не существует» — это вскользь упомянуто в посте, но не рассмотрено, а ведь сходить в базу (скорее всего асинхронно, 2024 год всё-таки) и проверить там наличие или отсутствие введённого значения всё равно так или иначе придётся;

  • валидация только при изменении — если значение не изменилось (опять же ходим в базу за старым значением), то свежедобавленные правила валидации не применяем, чтобы не злить старых пользователей;

    • более хитрый вариант — выполнить валидацию длины нового текста только если он длиннее старого (да, это реальная проверка, которую мне пришлось сделать на одном из моих сайтов);

  • локализация — не забываем, что тексты ошибок должны быть на родном пользователю языке и быть понятными ему (то есть, например, для встроенных валидаторов нужно заменить сухое «значение не соответствует регулярному выражению [A-Za-z0-9 ]+» на дружелюбное «допустимы только английские буквы, цифры и пробел»).

Из знакомого мне обработать всё это более-менее внятно может разве что Django Forms, но это древнее зло, про которое никто уже не вспоминает, а в современных проектах как будто никто даже не пытается разруливать такие вещи — все тупо выполняют валидацию на фронте, а ошибки с бэка иногда вообще не выводят, и приходится смотреть мониторинг сети в девтулзах, чтобы понять, что я ввёл не так :(

Парсинг — это, скорее, нечто простое: например, проверка, что полученная строка выглядит как ожидаемое число. В обозреваемых библиотеках уже начинается некоторая логика: например, проверить, что значение в поле age больше 21, где 21 взято из конфига сервиса. Или сказать, что карты Visa мы не поддерживаем, прочитав значение из поля card_number. Или удостовериться, что значение в поле country/currency соответствует ISO. Так же там можно выполнять косметические трансформации данных: например, приводить email к нижнему регистру

Если же у нас проверки, затрагивающие базу, то их лучше выполнять не на уровне со views, а на уровне с services (где бизнес-логика). Потому что там уже есть коннекшн к базе, плюс там и так будут какие-то манипуляции с базой: например, сначала проверить на существование, а потом создать новую сущность. Т.о., как по мне, вся эта часть уже вне скоупа рассматриваемых библиотек для валидации, это уже является бизнес логикой

Пункт про "валидация только при изменении" не уверен, что понял корректно. Если суть в том, что мы добавили какие-то правила на выходную схему, а миграцию данных в базе не провели, поэтому старые данные могут всё сломать, то так не надо делать :) Сначала вешаем ограничение на входные данные (чтобы в базе не прибавлялось чего-то невалидного), потом чистим значения в базе, и лишь потом включаем ограничения на выходные данные

С локализацией ошибок вроде можно довольно просто: бек отвечает, например, кодом ошибки и текстом в определенном формате, а фронт уже переводит в человекочитабельный вид, с учетом локали юзера. Если же не хотим забивать память фронта локализациями, то можно проворачивать эту конвертацию текста ошибки на беке в специальной middleware

Соглашусь, что правильная обработка ошибок и предоставление обратной связи пользователю — непростая тема. Порой от сообщения "что-то пошло не так, попробуйте еще раз" хочется пожать авторам горло

где 21 взято из конфига сервиса

А может, тоже из базы, если будут причины, по которым база окажется удобнее. Поскольку это ограничение не техническое, а скорее всего юридическое — выглядит как хороший кандидат для переноса в services

их лучше выполнять не на уровне со views, а на уровне с services (где бизнес-логика)

В итоге проверка входных данных рубится на две части (в особо запущенных случаях может и на три), и пользователь не сможет получить одновременно «Visa мы не поддерживаем» и «email уже используется» — ему придётся отправить форму два раза, чтобы получить обе ошибки по очереди. Похоже, с этим тоже никто не заморачивается, да и вообще звучит как мелочь, но вот лично мне такое неприятно и хочется поныть

потом чистим значения в базе

Я хочу оставить старые значения в покое и ограничить только новые. Так что, видимо, это тоже уезжает в services

бек отвечает, например, кодом ошибки

Наверное тоже вариант (и в каком-нибудь Cerberus примерно так и сделано), но заводить целый реестр кодов ошибок на каждый чих — чёт даже не знаю

(Я бы ещё поныл про рендеринг html-форм на стороне бэкенда с выводом всех этих ошибок валидации, но в 2024 году меня за такое определённо заклюют)

Pydantic обновил мажорную версию (вместе с ней и рекорды скорости).

появился очень крутой отечественный продукт на чистом питоне для конвертации/валидации данных из словаря в типизированные структуры и обратно - https://adaptix.readthedocs.io/en/latest/

Sign up to leave a comment.

Articles