Тип number() в Joi используется для строгой и гибкой
валидации числовых значений. Он позволяет проверять не только факт того,
что значение является числом, но и накладывать дополнительные
ограничения: диапазоны, целочисленность, знаки, точность и
математические свойства. В контексте серверной валидации это один из
наиболее часто применяемых типов, поскольку числовые данные встречаются
практически в любом API.
Схема начинается с создания числового валидатора:
const Joi = require('joi');
const schema = Joi.number();
По умолчанию Joi пытается привести входное значение к числу. Это
поведение называется coercion (приведение типов). Например,
строка "42" будет успешно преобразована в число
42.
В некоторых случаях автоматическое приведение нежелательно. Тогда используется строгая валидация:
const schema = Joi.number().strict();
Теперь значение "42" уже не пройдет проверку, так как
это строка, а не число.
Метод integer() ограничивает значения только целыми
числами:
const schema = Joi.number().integer();
Примеры поведения:
10 — допустимо10.5 — ошибка"10" — допустимо при включенном преобразовании
типовДля числовых диапазонов используются методы min() и
max():
const schema = Joi.number().min(0).max(100);
Такой валидатор пропустит значения от 0 до 100 включительно.
Пример ошибок:
-1 — меньше допустимого минимума101 — превышает максимумДля более точного контроля используются:
const schema = Joi.number().greater(0).less(100);
В отличие от min и max, здесь границы не
включаются:
0 — не допускается100 — не допускаетсяJoi предоставляет удобные методы для проверки знака числа:
Joi.number().positive();
Joi.number().negative();
positive() допускает только числа больше 0negative() допускает только числа меньше 0Метод multiple() позволяет проверить делимость
числа:
const schema = Joi.number().multiple(5);
Допустимые значения: 0, 5, 10, 15, 20
Недопустимые: 3, 7, 12
Метод precision() ограничивает количество знаков после
запятой:
const schema = Joi.number().precision(2);
Примеры:
10.12 — допустимо10.123 — ошибка10 — допустимоПо умолчанию Joi не допускает NaN и бесконечности:
Joi.number().allow(Infinity, -Infinity);
Или отдельно:
Joi.number().valid(Number.POSITIVE_INFINITY);
Однако в большинстве API такие значения считаются некорректными и запрещаются.
Числовое поле может быть обязательным:
const schema = Joi.number().required();
Или допускающим отсутствие:
const schema = Joi.number().optional();
Если число отсутствует, можно задать стандартное значение:
const schema = Joi.number().default(0);
При отсутствии поля в объекте оно автоматически получит значение
0.
Можно ограничить набор допустимых чисел:
const schema = Joi.number().valid(1, 2, 3, 5, 8);
Любое другое число вызовет ошибку валидации.
Joi позволяет переопределять текст ошибок:
const schema = Joi.number().min(0).messages({
'number.min': 'Число не может быть отрицательным'
});
Сила Joi заключается в комбинировании ограничений:
const schema = Joi.number()
.integer()
.min(10)
.max(100)
.positive()
.multiple(2);
Такой валидатор пропустит только:
Joi автоматически преобразует строки:
Joi.number().validate("123"); // 123
Однако это работает только если строка строго соответствует числу.
Значения вроде "123abc" вызовут ошибку.
undefined игнорируется, если поле не requirednull по умолчанию запрещёнРазрешение null:
Joi.number().allow(null);
Чаще всего number() применяется внутри схем
объектов:
const schema = Joi.object({
age: Joi.number().integer().min(0).max(120),
price: Joi.number().precision(2).positive(),
rating: Joi.number().min(1).max(5)
});
positive() и negative() одновременно)Частые проблемы при работе с number():
strict()integer() при работе с
идентификаторамиnullmin/max для пользовательских
значенийvalid() вместо диапазона, где требуется
гибкостьstrict() для финансовых и критичных
данныхmin/max для пользовательского
вводаprecision() для денежных значенийnull и
undefined