Fork me on GitHub
#clojure-russia
<
2018-09-03
>
dottedmag20:09:11

Возвращаясь к валидации внешних данных: схема подошла как раз, только там коэрсии встроенные перед валидацией, а не после. Коэрсии после валидации впрочем дописываются на раз-два через schema.spec.core/run-checker и обратная конверия "нормальные типы -> JSON" тоже без проблем.

guliy08:09:16

А как можно валидировать что-то до коэрции?

dottedmag08:09:39

Очень просто. Схема говорит "здесь разрешен только строковый ключ такого вида", а коэрсия коэрсит его в какое-то внутреннее представление.

dottedmag08:09:04

Например, схема может говорить "строка по регэкспу #"\d{2}INV-\d{8}#", а коэрсия превращает "77INV-08333333#" (без дополнительных проверок) в {:account/inventory-kind 8 :account/inventory-number 8333333}

guliy11:09:35

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

dottedmag12:09:36

У меня схема для внешних данных является, гм, схемой для внешних данных. Если валидация прошла, значит пришедший кусок данных валиден.

dottedmag12:09:16

Пост-коэрсеры схемы внешних данных конвертируют внешние данные во внутреннее представление. Выход пост-коэрсера должен быть валидным внутренним представлением.

dottedmag12:09:44

Спека описывает внутреннее представление, и это инвариант, который соблюдается внутри системы.

dottedmag12:09:38

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

dottedmag12:09:57

Так что у меня три сущности: 1) схема внешних данных; 2) набор правил для перевода из внешнего представления во внутреннее, прицепленный к внешней схеме; 3) спека внутреннего представления.

guliy12:09:52

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

dottedmag14:09:52

Мне важно поймать чуть-невалидные внешние данные. Например, если у меня есть коэрсия ключей "foo_bar" -> :foo-bar, то мне важно не пропустить ключ "foo-bar".

dottedmag14:09:01

Вместо того, чтобы делать это в коэрсерах, я это делаю в схеме. Кроме того, спека требует дополнительных телодвижений для "в этой мапе только такие ключи, а других нет", а в схеме это естественно.

akond15:09:45

спасибо, что поделился

guliy08:09:12

А вот, кстати, по поводу “в этой мапе только такие ключи, а других нет“. Как это решается? Я понимаю, что это противоречит концепции открытого мира, но все же интреесно как это обходится, если “очень нужно”

dottedmag10:09:59

В спеке нужно руками проверять, а в схеме это модель по умолчанию.

dottedmag10:09:27

Поэтому я и взял схему: она fail-closed, а не fail-open, как спека.

guliy11:09:42

Ну собсно я и спрашиваю как это руками проверять? Есть какие-то практики или реально бегать по мапке с сравнимать каждый ключ…?

dottedmag11:09:01

Я не видел готового. Потребовалось - сделал бы что-то вроде #(= (set (keys %)) #{...})

👍 4