Библиотека Joi предоставляет декларативный способ описания структуры данных и правил их валидации. В основе работы лежит понятие схемы — объекта, который описывает ожидаемую форму данных и ограничения для каждого поля.
Схемы позволяют централизованно определять правила проверки входных данных, что особенно важно при работе с API, формами и внешними источниками информации.
Наиболее часто используемая форма — объектная схема, создаваемая
через Joi.object().
const Joi = require('joi');
const schema = Joi.object({
name: Joi.string(),
age: Joi.number(),
email: Joi.string()
});
Каждое поле объекта описывается отдельной схемой. В данном примере:
name — строкаage — числоemail — строкаТакая схема задаёт только типы данных, без дополнительных ограничений.
По умолчанию все поля считаются необязательными. Для указания
обязательности используется метод required().
const schema = Joi.object({
name: Joi.string().required(),
age: Joi.number().required(),
email: Joi.string()
});
В этом случае отсутствие name или age
приведёт к ошибке валидации.
Строковые поля могут быть дополнены ограничениями длины, формата и содержимого.
const schema = Joi.object({
username: Joi.string()
.min(3)
.max(30)
.alphanum()
.required()
});
Используемые методы:
min(n) — минимальная длина строкиmax(n) — максимальная длина строкиalphanum() — только буквы и цифрыДополнительно часто применяется проверка на email:
const schema = Joi.object({
email: Joi.string()
.email()
.required()
});
Метод email() проверяет соответствие стандартному
формату электронной почты.
Для числовых значений применяются диапазоны и дополнительные проверки.
const schema = Joi.object({
age: Joi.number()
.integer()
.min(0)
.max(120)
});
Основные методы:
integer() — только целые числаmin(n) — минимальное значениеmax(n) — максимальное значениеТакже возможна проверка на положительные или отрицательные числа:
const schema = Joi.object({
score: Joi.number().positive(),
debt: Joi.number().negative()
});
Булевы поля описываются через Joi.boolean().
const schema = Joi.object({
isActive: Joi.boolean(),
isAdmin: Joi.boolean().required()
});
Допустимые значения автоматически приводятся к логическому типу при включённых опциях преобразования.
Схемы могут быть вложенными, что позволяет описывать сложные структуры данных.
const schema = Joi.object({
user: Joi.object({
name: Joi.string().required(),
age: Joi.number().required()
}),
isActive: Joi.boolean()
});
Каждый уровень вложенности также описывается через
Joi.object().
Для описания массивов используется Joi.array() с
указанием типа элементов.
const schema = Joi.object({
tags: Joi.array().items(Joi.string()),
scores: Joi.array().items(Joi.number())
});
Метод items() задаёт схему элементов массива.
Дополнительно могут применяться ограничения:
const schema = Joi.object({
tags: Joi.array()
.items(Joi.string())
.min(1)
.max(5)
});
Схемы позволяют задавать значения, которые будут подставлены при отсутствии данных.
const schema = Joi.object({
role: Joi.string().default('user'),
isActive: Joi.boolean().default(true)
});
Метод default() определяет значение, используемое при
отсутствии поля.
В некоторых случаях требуется исключить определённые значения.
const schema = Joi.object({
role: Joi.string().invalid('admin', 'superuser')
});
Метод invalid() запрещает указанные значения.
Альтернативный вариант — использование valid() для
перечисления допустимых значений:
const schema = Joi.object({
role: Joi.string().valid('user', 'moderator', 'guest')
});
Иногда структура объекта неизвестна заранее. Для таких случаев
применяется unknown(true).
const schema = Joi.object({
name: Joi.string()
}).unknown(true);
Такой подход разрешает наличие дополнительных полей, не описанных в схеме.
Схемы могут использоваться и без Joi.object(), описывая
отдельные значения.
const schema = Joi.string().min(5).max(10);
Или:
const schema = Joi.number().integer().positive();
Такие схемы применяются для проверки одиночных значений, например параметров URL или отдельных полей запроса.
Методы Joi поддерживают цепочки вызовов, позволяя комбинировать ограничения в одном выражении.
const schema = Joi.object({
password: Joi.string()
.min(8)
.max(64)
.pattern(/^[a-zA-Z0-9!@#\$%\^&\*]+$/)
.required()
});
Метод pattern() добавляет регулярное выражение для
проверки строки.
Для случаев, когда допустимы разные типы данных, используется
alternatives().
const schema = Joi.alternatives().try(
Joi.string(),
Joi.number()
);
Это позволяет принимать либо строку, либо число в одном поле.