clojure-russia

Работа и релокейт: #jobs-rus | #clojure-russia-offtop Телеграм-чат https://t.me/clojure_ru
dottedmag 2018-09-03T20:58:11.000100Z

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

guliy 2018-09-04T08:28:16.000100Z

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

dottedmag 2018-09-04T08:53:39.000100Z

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

dottedmag 2018-09-04T08:55:04.000100Z

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

guliy 2018-09-04T11:24:35.000100Z

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

dottedmag 2018-09-04T12:51:36.000100Z

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

dottedmag 2018-09-04T12:52:16.000100Z

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

dottedmag 2018-09-04T12:52:44.000100Z

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

dottedmag 2018-09-04T12:53:38.000100Z

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

dottedmag 2018-09-04T12:54:57.000100Z

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

guliy 2018-09-04T12:58:52.000100Z

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

dottedmag 2018-09-04T14:12:52.000100Z

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

dottedmag 2018-09-04T14:14:01.000100Z

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

akond 2018-09-04T15:13:45.000100Z

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

guliy 2018-09-05T08:06:12.000100Z

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

dottedmag 2018-09-05T10:32:59.000100Z

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

dottedmag 2018-09-05T10:33:27.000100Z

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

guliy 2018-09-05T11:04:42.000100Z

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

dottedmag 2018-09-05T11:22:01.000100Z

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

👍 1