Как стать автором
Обновить
12
0
koorchik @koorchik

Пользователь

Отправить сообщение

Возможно будет тоже полезно. Для JavaScript, кроме основных правил, есть отдельный пакет с дополнительными правилами — https://www.npmjs.com/package/livr-extra-rules и он тоже zero dependencies :)

Chatscript на самом деле расчитан именно на большое количество правил и на очень высокую скорость работы. Тысячи правил и тысячи одновременных пользователей — это совершенно нормально для ChatScript, кроме того это не просто матчинг, синтаксический разбор фраз на части речи, приведение времен — все это сильно облегчает написание правил (и сократить их количество) и позволяет сделать код более поддерживаемым и универсальным.
Относительно других языков, все сложнее. ChatScript поддерживает подключаемы синтаксические парсеры для других языков, но самих таких парсеров не так много. А что есть — слишком медленные.


Системы на базе ChatScript четыре раза получали Лёбнера. Отличная статья про это — https://github.com/bwilcox-1234/ChatScript/blob/master/WIKI/PAPERS/Paper%20-%20WinningTheLoebners.md

У нас в проектах мы сделали правило required_if


И пишем так:


{    
    optedInForNewsletter: {one_of: [1, 0]},
    email:  [{required_if: 'optedInForNewsletter'}, 'email'],
}

Ну тогда просто делается end-point, который будет репортить статус опираясь на LA к примеру (ну или на любую другую метрику)

Отличная статья. Единственное, есть уточнение по:


Если ваш бэкенд отчаянно пятисотит [выдаёт код состояния HTTP 5XX, что говорит об ошибке сервера] и не справляется, то балансировщик думает, что бэкэнд очень быстро отдает ответы, и начинает слать ему ещё больше трафика, загибая ваш бэкэнд ещё сильнее.

ELB проверяет жизнь инстанса по настраиваемому URL. И 500-я ошибка говорит о том, что нужно выбросить инстанс с пула. То есть, если ELB смотрит на пользовательскую страницу и она вернет ошибку 500, то он корректно отработает. Зачастую этого достаточно.

С таким доходом есть ряд проблем:


  1. Не ясно, как адресовать вложенные структуры. Можно конечно писать {required: ['address.city']} или {required: ['address/city'], но нужно помнить про массивы и тд.
  2. Не ясно в каком порядке применяются правила. Например, {required: ['email'], trim: ['email'] }. Конечно можно записывать [{required: ['email']}, {trim: ['email'] }], но все равно остается вопрос приоритета, если у меня уже есть уточняющие правила в основной структуре, типа {email: 'to_lc'}. В каком порядке применятся дополнительные правила? Конечно можно решить, что приоритет такой вот, но это не всем подойдет, во-вторых, нужно всегда помнить про этот приоритет.
  3. Вопрос безопасности. Если сейчас я удалю валидацию для поля, то поля будет вырезано валидатором и могу быть уверен, что никто ничего в нем не передаст. Если же описывать в перевернутом виде, то нужно будет постоянно помнить, что где-то это поле могло быть упомянуто.

Кроме того, можно сделать функцию типа applyCommonRules(livr, commonRules) и просто преобразовывать один формат в другой. Мощь LIVR в том, что это просто структура данных и можно делать с этими данными любые операции. Написать такую функцию займет полчаса времени и позволит увидеть в реальном проекте нужно ли это на уровне спецификации или может быть просто сторонней библиотекой (ну и ее можно зарелизить в opensource)

Вышел LIVR 2.0 (http://livr-spec.org/) С новых фич:

Согласованный подход к работе с типами.
«Base rules» переименовали в «Common rules».
«Filter rules» переименовали в «Modifiers». Поскольку они ничего не валидируют, а только модифицируют данные.
«Helper rules» переименовали to «Metarules»
Добавлено правило «any_object», проверяет, что это объект
Добавлено правило строка — «string», просто строка любого типа
Добавлено правило «eq» — проверяет на строковое равенство
Добавлено метаправило «variable_object». Динамически определяет, какую валидацию использвоать в зависимосте от полей в объекте.
Добавлено метаправило «or». Позволяет применять правила поочередно до первого совпадения.
Добавлен модификтор «default» для установки значений по-умолчинаю, если пользователь ничего не передал.
Значительно расширен комплект тестов.

JavaScript реализация уже поддерживает все новые функции, остальные реализации в процессе обновления.
Для такой задачи в LIVR 0.4 были добавлены алиасы. Когда правило можно скомбинировать на базе других, дать ему название и дать свой код ошибки (опционально). Естественно, это не покрывает все ситуации, но многие проблемы решает.
Все зависит от задач. JSON Schema имеет свои сисльные стороны и уникальные возможности. JSON Schema прекрасно подойдет в случаях, когда:
  • Вас не пугает многословный синтаксис
  • Нет потребовности в кастомных правилах со сложной логикой
  • Нет необходимости добавлять филтры, типа trim, to_lc и так далее
  • Нет потребоности в стандартизации ошибок
  • Нет нужно получать ошибки сразу для всех полей, включая вложенные структуры данных.


Но нужно, например, разрешить неописанные поля.

Относительно «additionalProperties», то в JSON Schema, по-умолчанию, разрешены все дополнительные поля. Что, я считаю, тоже недостатком:

Проблема №1. Многие валидаторы проверяют только те данные, для которых описаны правила проверки. Для меня важно, чтобы любой пользовательский ввод, который явно не разрешен, был проигнорирован. То есть, валидатор должен вырезать все данные для которых не описаны правила валидации. Это просто фундаментально требование.


По поводу правила «list_of», то это не так особенность валидатора, как правила. Валидатор очень гибкий и позволяет реализовать любые правила.

В общем, основной мой посыл в том, что инструмент подбирается под задачи и есть задачи, где JSON Schema удобней, а есть, где удобней будет LIVR
«multipleOf» без проблем реализуется, но не хочется добавлять вещи в спеку, которые никто не будет использовать. Если уж возникнет такой случай, то в проекте всегда можно описать свое правило. LIVR легко расширить практически любой функциональностью. Не знаю возможно ли такое в JSON Schema. Относительно описания своих типов и сохранения их в отельный файл, то для этого отлично походят алиасы.

Относительно генирации html-форм, то можно было бы попробовать написать библиотеку, но на моей практике от таких инструментов для меня никакой пользы не было.
Относительно этой схемы, то тут нужно будет описать некоторые правила/алиасы (аналог oneOf). Пример хороший, создал тикет github.com/koorchik/LIVR/issues/14, воможно добавим пару правил на уровень спецификации в LIVR 0.5
Да, все верно. Это совсем простой кейс, по которому можно сравнить описание на LIVR и JSON Schema. На LIVR получается явно лаконичние:

{
    order_id: ['required', 'positive_integer'],
    product_ids: [{
       'list_of': [ 'required',  'positive_integer' ]
    }]
}


Кроме того, остается остальные вышеупомянутые проблемы. Относительно софта — тоже верно. Например, пока нет LIVR для Ruby, но я думаю, если будет необходимость, найдутся желающие портировать.
Сейчас согласовываем апдейт к LIVR v0.5 — github.com/koorchik/LIVR/labels/proposal. Оставляйте свои комментарии/замечания.

Из нового, что уже решили добавлять в спеку — правило «any» — github.com/koorchik/LIVR/compare/v0.5.
Исправили, проявлялось только в JS реализации. Расширили тестовый комлпект для спеки.
Обновили тесты, исправили, проявлялось только в JS реализации.
В JS реализации не идеальная проверка. Хотя Perl-реализации полностью по RFC. Спасибо, добавим пару доп. тестов в тестовый комплект спецификации и попросим авторов реализаций обновить тесты.  
Да, это возможно и делается достаточно просто:

var LIVR = require('livr');

var requiredIfFieldEmpty = function(field) {
    return function(value, fields) {
        var isDependentFieldEmpty = fields[field] === null || fields[field] === undefined || fields[field] === '';
        var isTargetFieldEmpty = value === null || value === undefined || value === '';

        if (isDependentFieldEmpty && isTargetFieldEmpty) {
            return 'REQUIRED'
        }
    }
};

LIVR.Validator.registerDefaultRules({ required_if_field_empty: requiredIfFieldEmpty});

var validator = new LIVR.Validator({
     phone: {required_if_field_empty: 'email'},
     email: {required_if_field_empty: 'phone'},
});
Проблема высосана из пальца:
1) Регулярки в PHP, JS, Python и других языках очень близки. Очень редко нужны фичи регулярок, которые доступны только на одной платформе. Ок, в JS регулярках не поддерживается lookbehind, но много ли у вас таких регулярок? За такой совместимостью следить не большая проблема.
2) Просмотрел несколько наших проектов — «like» практически нигде не нужен. Намного удобней добавить свое правило, чтобы не копипастить регулярку по 10 модулям. Например, для проверки суммы, мы не используем «like», а создаем свое правило «positive_amount». Это как вынести повторяющийся код в функцию и дать ей нормальное название. Например, у нас есть такие правила «valid_phone», «valid_url», «alphanumeric», «company_id», «uppercase_latin_symbols». Вместо всех них можно было везде писать было бы «like», но это значительно хуже в поддержке.
3) Определение своих правил позволяет выдавать более информативные ошибки. Например, «positive_amount» у нас возвращает WRONG_AMOUNT_FORMAT, AMOUNT_TOO_SMALL, AMOUNT_TOO_LARGE. Эти ошибки затем локализируются и показываются в виде сообщений пользователю. Это намного информативней, чем просто WRONG_FORMAT, который возвращает «like».
4) Можно написать пару тестов для кастомных правил (да и для бизнес-логики тоже), что будет полезно в любом случае.
5) Можно переопределить «like» (или добавить какое-то свое правило, типа «match») и разрешить принимать регулярки (или просто wildcards) только в определенном формате.
6) Указывать версии для разных платформ не даст особого выигрыша, поскольку очень низка вероятность, что в каждой версии вы решите использовать фичи доступные только на конкретной платформе. Одна из версий у вас будет работать на всех платформах, ее и оставляйте.
7) Мир не идеален, абстракции текут, но здравый смысл всех спасет :). То есть, если не вдаваться в крайности и решать практические задачи, то все работает.
8) Спецификация не является чем-то закрытым — она развивается, принимаются пожелания и замечания. Если при решении практических задач вы упретесь в ограничения LIVR, это будет отличным поводом для развития спецификации.
9) У нас в компании LIVR круто себя показал, даже в тех проектах, где он используется только для бекенда. По принципу «Learn once, use everywhere».
10) Инструмент выбирается из задач и я верю, что есть ситуации, когда LIVR может и не подойти )
Вы правы, в случае с десятичными положительные числа начинаются не с единицы :). Спасибо — исправим.
В целом, да. В email разрешен юникод.

Информация

В рейтинге
Не участвует
Откуда
Украина
Дата рождения
Зарегистрирован
Активность