Валидация строковых значений в Joi начинается с управления их
размером. Основные методы контроля — min() и
max(), задающие допустимые границы длины строки в
символах.
import Joi from 'joi';
const schema = Joi.object({
username: Joi.string()
.min(3)
.max(30)
});
В этом примере строка username должна содержать от 3 до
30 символов включительно. Если значение выходит за пределы, Joi
формирует ошибку валидации с типом string.min или
string.max.
При работе с Unicode-строками важно учитывать, что длина измеряется в символах JavaScript, а не в байтах. Это означает, что эмодзи и сложные символы могут занимать больше одного байта, но для Joi это всё равно один символ.
Дополнительно можно уточнять поведение пробельных символов, используя предварительную обработку:
const schema = Joi.object({
title: Joi.string()
.trim()
.min(5)
.max(100)
});
Метод trim() позволяет исключить влияние пробелов в
начале и конце строки, что особенно важно при ограничениях минимальной
длины.
Для числовых данных ограничения размера выражаются через диапазоны.
Основные методы — min(), max() и
greater(), less().
const schema = Joi.object({
age: Joi.number()
.min(0)
.max(120)
});
Такое определение гарантирует, что значение находится в допустимом диапазоне человеческого возраста.
Более строгие условия задаются через исключение границ:
const schema = Joi.object({
score: Joi.number()
.greater(0)
.less(100)
});
Здесь значение должно быть строго больше 0 и строго меньше 100.
Joi также поддерживает проверку целочисленных значений:
const schema = Joi.object({
quantity: Joi.number()
.integer()
.min(1)
.max(1000)
});
Это важно при ограничении размеров партий, количества элементов или других дискретных величин.
Массивы требуют отдельного подхода, так как их «размер» выражается
числом элементов. Для этого используются методы min(),
max() и length().
const schema = Joi.object({
tags: Joi.array()
.items(Joi.string())
.min(1)
.max(10)
});
Такое правило задаёт диапазон допустимого количества тегов.
Если требуется строго фиксированное количество элементов,
используется length():
const schema = Joi.object({
coordinates: Joi.array()
.length(2)
.items(Joi.number())
});
Здесь массив обязан содержать ровно два числовых элемента.
Для более сложных структур возможно комбинирование ограничений на элементы и общий размер:
const schema = Joi.object({
permissions: Joi.array()
.items(Joi.string().valid('read', 'write', 'delete'))
.min(1)
.max(3)
.unique()
});
Метод unique() дополнительно ограничивает повторяющиеся
значения, что влияет на логический размер множества данных.
Хотя объект не имеет прямого «размера» в байтах в Joi, его сложность ограничивается количеством ключей и глубиной вложенности.
Для ограничения количества полей используется .max() и
.min() на уровне объекта:
const schema = Joi.object({
profile: Joi.object({
name: Joi.string(),
age: Joi.number()
}).min(1).max(5)
});
Эти ограничения применяются к числу разрешённых ключей внутри объекта.
Для предотвращения избыточной структуры часто применяется строгая схема:
const schema = Joi.object({
id: Joi.number(),
email: Joi.string()
}).unknown(false);
Параметр unknown(false) запрещает дополнительные поля,
тем самым фиксируя размер объекта на уровне схемы.
При работе с буферами используется контроль длины в байтах:
const schema = Joi.object({
file: Joi.binary()
.min(1024)
.max(5 * 1024 * 1024)
});
В этом случае проверяется размер файла от 1 КБ до 5 МБ. Это особенно важно при загрузке изображений, архивов и других бинарных данных.
Сложные структуры требуют контроля на нескольких уровнях. Например, массив объектов с ограничениями внутри:
const schema = Joi.object({
users: Joi.array().items(
Joi.object({
id: Joi.number().min(1),
name: Joi.string().max(50)
})
).max(100)
});
Здесь ограничивается как количество пользователей, так и размер каждого объекта.
При необходимости можно комбинировать ограничения глубины через рекурсивные схемы:
const nodeSchema = Joi.object({
value: Joi.string().max(20),
children: Joi.array().items(Joi.link('#node')).max(5)
}).id('node');
Это позволяет контролировать разветвлённость структуры данных.
Ограничения на размер данных напрямую влияют на производительность валидации. Чем больше допустимый объём структуры, тем выше стоимость проверки.
Особенно критичны:
В таких случаях Joi выполняет обход всей структуры, что увеличивает время проверки пропорционально размеру данных.
Оптимизация достигается за счёт:
max() на верхнем уровне);unknown(true);Joi позволяет задавать собственные сообщения для разных типов превышений:
const schema = Joi.object({
password: Joi.string()
.min(8)
.max(64)
.messages({
'string.min': 'Пароль слишком короткий',
'string.max': 'Пароль превышает допустимую длину'
})
});
Это особенно важно при работе с пользовательскими интерфейсами, где требуется точная диагностика нарушения ограничений.
Ограничения размера данных формируют не только защиту от некорректного ввода, но и определяют контракт между системами. Чётко заданные границы позволяют:
Joi выступает в этом контексте как декларативный слой описания допустимого объёма и формы данных, обеспечивая строгую структуру без необходимости ручной проверки каждого поля.