Joi представляет собой декларативную систему описания и проверки структур данных, где основой выступают схемы (schemas). Первая схема валидации формирует базовое понимание того, как библиотека описывает ожидаемую структуру объекта и как происходит проверка входных данных.
Схема в Joi — это объект, описывающий правила для конкретного значения или структуры данных. Каждое поле данных получает набор ограничений: тип, обязательность, допустимые значения, формат.
Ключевой момент: схема не изменяет данные, а лишь проверяет их соответствие.
Перед созданием первой схемы необходимо получить доступ к объекту Joi:
const Joi = require('joi');
После этого становится доступен набор методов для описания типов данных:
Joi.string() — строкаJoi.number() — числоJoi.boolean() — булев типJoi.object() — объектJoi.array() — массивБазовая схема обычно начинается с описания объекта через
Joi.object().
const schema = Joi.object({
name: Joi.string(),
age: Joi.number()
});
Здесь определены два поля:
name — строкаage — числоТакая схема уже задаёт структуру данных, но пока не накладывает строгих ограничений.
Для контроля обязательности используется метод
required():
const schema = Joi.object({
name: Joi.string().required(),
age: Joi.number().required()
});
Теперь оба поля становятся обязательными. Отсутствие любого из них приведёт к ошибке валидации.
Валидация выполняется через метод validate:
const data = {
name: 'Alex',
age: 25
};
const result = schema.validate(data);
Метод возвращает объект результата, содержащий:
value — нормализованные данныеerror — описание ошибки (если она есть)Типичная структура результата:
{
value: { name: 'Alex', age: 25 },
error: undefined
}
При ошибке:
{
value: { ... },
error: ValidationError
}
Объект error содержит подробности: какое поле нарушило
правило и почему.
По умолчанию Joi прекращает проверку после первой ошибки. Это
поведение регулируется опцией abortEarly.
const result = schema.validate(data, {
abortEarly: false
});
При установке false будут собраны все ошибки сразу, а не
только первая.
Joi строго различает типы. Например, строка и число не взаимозаменяемы:
const schema = Joi.object({
age: Joi.number()
});
Если передать строку:
schema.validate({ age: "25" });
валидация завершится ошибкой, даже если значение выглядит корректным.
Первая схема часто расширяется дополнительными ограничениями:
const schema = Joi.object({
name: Joi.string().min(3).max(30).required(),
age: Joi.number().min(0).max(120).required()
});
Здесь вводятся:
Пустые значения обрабатываются отдельно. Например, пустая строка не считается отсутствием поля:
const schema = Joi.object({
name: Joi.string().required()
});
Значение "" пройдёт проверку на наличие поля, но может
нарушить дополнительные ограничения.
Joi не только проверяет данные, но и приводит их к ожидаемому виду:
const schema = Joi.object({
age: Joi.number()
});
schema.validate({ age: "42" });
Результат:
{ age: 42 }
Приведение типов происходит автоматически, если это возможно без потери смысла.
Первая схема выполняет роль базового контракта данных. Она определяет:
На этом этапе формируется основа для дальнейшего усложнения валидации: вложенные объекты, массивы, кастомные правила.
На практике первая схема часто выглядит как предельно простая конструкция:
const schema = Joi.object({
id: Joi.number().required()
});
Даже такая схема уже задаёт строгий контракт между источником данных и логикой приложения.