Joi представляет собой библиотеку для описания схем данных и их последующей валидации в JavaScript-приложениях. Основная задача инструмента заключается в формализации структуры входящих данных и обеспечении их соответствия заранее заданным правилам. Подход основан на декларативном описании ограничений, при котором данные проверяются на соответствие типам, диапазонам, форматам и логическим условиям.
Использование Joi особенно распространено в серверных приложениях на Node.js, где требуется контроль входящих запросов: параметры HTTP, тела запросов, данные форм, конфигурации и внешние интеграции. Отсутствие валидации приводит к неконтролируемым ошибкам, уязвимостям и нестабильному поведению системы.
В основе работы Joi лежит понятие схемы. Схема описывает структуру данных и набор правил, которым эти данные должны соответствовать. Проверка осуществляется путем сравнения входного значения с описанием схемы.
Простейшая схема для строки:
const Joi = require('joi');
const schema = Joi.string();
Такая схема определяет, что допустимым значением является любая строка.
Валидация выполняется через метод validate:
const result = schema.validate('тестовая строка');
Результат содержит информацию об ошибке и преобразованное значение.
Библиотека устанавливается через менеджер пакетов npm:
npm install joi
Подключение осуществляется стандартным способом:
const Joi = require('joi');
В проектах с ES Modules используется:
import Joi from 'joi';
Joi предоставляет набор базовых типов, соответствующих примитивам JavaScript.
const schema = Joi.string();
Добавление ограничений:
const schema = Joi.string().min(3).max(30);
Проверка форматов:
const schema = Joi.string().email();
Регулярные выражения:
const schema = Joi.string().pattern(/^[a-zA-Z0-9]+$/);
const schema = Joi.number();
Ограничения диапазона:
const schema = Joi.number().min(0).max(100);
Проверка целых чисел:
const schema = Joi.number().integer();
const schema = Joi.boolean();
Допустимые значения: true и false.
По умолчанию поля считаются необязательными. Для изменения поведения
используется метод required:
const schema = Joi.string().required();
Обратное поведение:
const schema = Joi.string().optional();
Значения по умолчанию:
const schema = Joi.string().default('значение по умолчанию');
При отсутствии данных будет использовано заданное значение.
Одним из ключевых сценариев применения Joi является валидация объектов.
const schema = Joi.object({
username: Joi.string().min(3).required(),
age: Joi.number().min(18),
email: Joi.string().email()
});
Проверка:
const data = {
username: 'user1',
age: 25,
email: 'test@mail.com'
};
const result = schema.validate(data);
const schema = Joi.object({
user: Joi.object({
name: Joi.string().required(),
profile: Joi.object({
bio: Joi.string(),
website: Joi.string().uri()
})
})
});
Joi поддерживает строгую типизацию массивов:
const schema = Joi.array().items(Joi.string());
Ограничение длины:
const schema = Joi.array().min(1).max(5);
Массив объектов:
const schema = Joi.array().items(
Joi.object({
id: Joi.number(),
name: Joi.string()
})
);
Для случаев, когда данные могут соответствовать нескольким схемам,
используется alternatives:
const schema = Joi.alternatives().try(
Joi.string(),
Joi.number()
);
Это позволяет принимать значения разных типов в рамках одного поля.
Метод validate принимает дополнительные параметры,
влияющие на поведение проверки.
Останавливает проверку при первой ошибке:
const result = schema.validate(data, { abortEarly: false });
Разрешает наличие неизвестных полей в объектах:
const schema = Joi.object({
name: Joi.string()
}).unknown(true);
Удаляет лишние поля из результата:
const result = schema.validate(data, { stripUnknown: true });
Включает автоматическое приведение типов:
const result = schema.validate('123', { convert: true });
Joi позволяет настраивать текст ошибок:
const schema = Joi.string().min(3).messages({
'string.min': 'Строка слишком короткая'
});
Ошибки структурированы по типам, что упрощает обработку на уровне приложения.
Для более сложных сценариев используется метод
custom:
const schema = Joi.string().custom((value, helpers) => {
if (value === 'admin') {
return helpers.error('any.invalid');
}
return value;
});
Позволяет реализовать произвольную бизнес-логику проверки.
Схемы могут комбинироваться через concat:
const base = Joi.string().min(3);
const extended = base.concat(Joi.string().max(10));
Это полезно при переиспользовании правил.
Joi поддерживает расширения через создание собственных правил:
const customJoi = Joi.extend((joi) => ({
type: 'positive',
base: joi.number(),
validate(value, helpers) {
if (value < 0) {
return { value, errors: helpers.error('number.positive') };
}
}
}));
Позволяет добавлять новые типы и правила поверх существующей системы.
Joi способен не только проверять, но и преобразовывать данные:
Пример:
const schema = Joi.number();
const result = schema.validate('42');
Результатом будет число 42, если включено
преобразование.
const schema = Joi.date();
Ограничения:
const schema = Joi.date().greater('now');
Поддерживаются ISO-форматы и JavaScript Date.
Система валидации на основе Joi часто используется на границах приложения:
Структурированное описание схем снижает количество ошибок на уровне бизнес-логики и отделяет проверку данных от основной функциональности кода.