Введение в Joi: что это и зачем нужно
Joi — это мощная библиотека для валидации данных в среде JavaScript (Node.js). Она позволяет описывать схемы данных с помощью простого и выразительного API, а затем проверять соответствие реальных объектов этим схемам. Joi особенно популярна при разработке серверной части веб-приложений, где необходимо проверять входящие запросы, конфигурации, данные из форм и любые другие структуры данных.
Основные причины использовать Joi:
- Безопасность: предотвращает попадание некорректных или вредоносных данных в ваше приложение
- Читаемость кода: схемы Joi легко читаются и понимаются
- Гибкость: поддерживает сложные вложенные структуры, условную валидацию и кастомные правила
- Интеграция: отлично работает с Express, Koa, Fastify и другими фреймворками
- Детальные ошибки: предоставляет понятные сообщения об ошибках с указанием точного места проблемы
Установка Joi
Установка Joi в проект Node.js выполняется через npm или yarn:
# Через npm
npm install joi
# Через yarn
yarn add joi
# Если вы используете TypeScript, установите типы (опционально)
npm install @types/joi --save-dev
После установки вы можете импортировать Joi в свой проект:
const Joi = require('joi');
// или для ES модулей:
// import Joi from 'joi';
Быстрый старт: первый пример валидации
Давайте создадим простую схему для валидации данных пользователя и проверим её работу:
const Joi = require('joi');
// Определяем схему валидации
const schema = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),
password: Joi.string()
.pattern(new RegExp('^[a-zA-Z0-9]{3,30}$')),
email: Joi.string()
.email({ minDomainSegments: 2, tlds: { allow: ['com', 'net'] } })
});
// Данные для проверки
const userData = {
username: 'john_doe',
password: 'myPassword123',
email: 'john@example.com'
};
// Выполняем валидацию
const { error, value } = schema.validate(userData);
if (error) {
console.log('Ошибка валидации:', error.details);
} else {
console.log('Данные валидны:', value);
}
В этом примере мы создали схему для объекта с тремя полями. Метод validate() возвращает объект с двумя свойствами: error (если есть ошибки) и value (валидированные данные).
Основные методы Joi
1. Joi.string() — Валидация строк
Что делает: Создаёт валидатор для строковых значений. Предоставляет множество методов для проверки длины, формата, содержания и других характеристик строки.
Параметры: Без параметров. Возвращает объект валидатора, к которому можно применять цепочку методов.
Пример:
const schema = Joi.string()
.min(3) // минимальная длина 3 символа
.max(10) // максимальная длина 10 символов
.alphanum() // только буквы и цифры
.required(); // обязательное поле
console.log(schema.validate('Hello')); // { value: 'Hello' }
console.log(schema.validate('Hi')); // { error: ... } - слишком короткая строка
console.log(schema.validate('Hello123')); // { value: 'Hello123' }
console.log(schema.validate('Hello!')); // { error: ... } - содержит спецсимволы
2. Joi.number() — Валидация чисел
Что делает: Создаёт валидатор для числовых значений. Позволяет проверять диапазон, целочисленность, положительность и другие свойства чисел.
Параметры: Без параметров. Поддерживает цепочку методов для настройки.
Пример:
const schema = Joi.number()
.integer() // только целые числа
.min(0) // минимальное значение 0
.max(100) // максимальное значение 100
.positive(); // только положительные числа
console.log(schema.validate(42)); // { value: 42 }
console.log(schema.validate(-5)); // { error: ... } - отрицательное число
console.log(schema.validate(3.14)); // { error: ... } - не целое число
console.log(schema.validate(150)); // { error: ... } - превышает максимум
3. Joi.boolean() — Валидация булевых значений
Что делает: Создаёт валидатор для булевых значений (true/false). Может преобразовывать строки "true"/"false" в соответствующие булевы значения.
Параметры: Без параметров.
Пример:
const schema = Joi.boolean()
.truthy('yes') // считать 'yes' как true
.falsy('no') // считать 'no' как false
.required();
console.log(schema.validate(true)); // { value: true }
console.log(schema.validate(false)); // { value: false }
console.log(schema.validate('yes')); // { value: true } - преобразовано
console.log(schema.validate('no')); // { value: false } - преобразовано
console.log(schema.validate('abc')); // { error: ... } - невалидное значение
4. Joi.array() — Валидация массивов
Что делает: Создаёт валидатор для массивов. Позволяет проверять длину массива, типы элементов, уникальность значений и другие свойства.
Параметры: Без параметров. Использует методы для настройки валидации элементов.
Пример:
const schema = Joi.array()
.items(Joi.string()) // элементы должны быть строками
.min(1) // минимум 1 элемент
.max(5) // максимум 5 элементов
.unique() // элементы должны быть уникальными
.required();
console.log(schema.validate(['a', 'b', 'c'])); // { value: ['a', 'b', 'c'] }
console.log(schema.validate([])); // { error: ... } - пустой массив
console.log(schema.validate(['a', 'a'])); // { error: ... } - дубликаты
console.log(schema.validate([1, 2, 3])); // { error: ... } - не строки
5. Joi.object() — Валидация объектов
Что делает: Создаёт валидатор для объектов. Позволяет определять схему для каждого поля объекта, включая вложенные объекты и массивы.
Параметры: Принимает объект с описанием полей и их валидаторов.
Пример:
const schema = Joi.object({
name: Joi.string().required(),
age: Joi.number().integer().min(0).max(150),
address: Joi.object({
street: Joi.string().required(),
city: Joi.string().required(),
zip: Joi.string().pattern(/^\d{5}$/)
}),
hobbies: Joi.array().items(Joi.string())
});
const validData = {
name: 'Alice',
age: 30,
address: {
street: '123 Main St',
city: 'New York',
zip: '10001'
},
hobbies: ['reading', 'swimming']
};
console.log(schema.validate(validData)); // { value: validData }
6. Joi.date() — Валидация дат
Что делает: Создаёт валидатор для дат. Поддерживает проверку формата, диапазона дат, сравнение с текущей датой и другие операции.
Параметры: Без параметров.
Пример:
const schema = Joi.date()
.iso() // только ISO формат
.min('2023-01-01') // минимальная дата
.max('2024-12-31') // максимальная дата
.required();
console.log(schema.validate('2023-06-15')); // { value: '2023-06-15' }
console.log(schema.validate('2022-12-31')); // { error: ... } - раньше минимальной
console.log(schema.validate('2025-01-01')); // { error: ... } - позже максимальной
console.log(schema.validate('invalid-date')); // { error: ... } - невалидный формат
7. Joi.alternatives() — Альтернативные схемы
Что делает: Позволяет определить несколько возможных схем для одного значения. Значение считается валидным, если оно соответствует хотя бы одной из указанных схем.
Параметры: Принимает массив схем через метод try() или условные схемы через conditional().
Пример:
const schema = Joi.alternatives().try(
Joi.string().valid('admin', 'user'),
Joi.number().integer().min(1).max(100)
);
console.log(schema.validate('admin')); // { value: 'admin' }
console.log(schema.validate(42)); // { value: 42 }
console.log(schema.validate('guest')); // { error: ... } - не соответствует ни одной схеме
console.log(schema.validate(101)); // { error: ... } - не соответствует ни одной схеме
8. Joi.any() — Универсальный валидатор
Что делает: Создаёт валидатор, который принимает любое значение. Полезен для полей, тип которых неизвестен заранее, или для создания кастомных правил валидации.
Параметры: Без параметров.
Пример:
const schema = Joi.any()
.valid('value1', 'value2', 42) // только эти значения разрешены
.required();
console.log(schema.validate('value1')); // { value: 'value1' }
console.log(schema.validate(42)); // { value: 42 }
console.log(schema.validate('other')); // { error: ... } - недопустимое значение
9. Joi.binary() — Валидация бинарных данных
Что делает: Создаёт валидатор для бинарных данных (Buffer). Позволяет проверять размер, кодировку и другие свойства бинарных данных.
Параметры: Без параметров.
Пример:
const schema = Joi.binary()
.min(10) // минимальный размер в байтах
.max(1000) // максимальный размер в байтах
.encoding('base64') // ожидаемая кодировка
.required();
const validBuffer = Buffer.from('Hello World!', 'utf8');
const smallBuffer = Buffer.from('Hi', 'utf8');
console.log(schema.validate(validBuffer)); // { value: }
console.log(schema.validate(smallBuffer)); // { error: ... } - слишком маленький
10. Joi.function() — Валидация функций
Что делает: Создаёт валидатор для функций. Позволяет проверять количество аргументов, наличие определённых свойств и другие характеристики функций.
Параметры: Без параметров.
Пример:
const schema = Joi.function()
.arity(2) // функция должна принимать 2 аргумента
.minArity(1) // минимум 1 аргумент
.maxArity(5) // максимум 5 аргументов
.required();
function add(a, b) {
return a + b;
}
function greet(name) {
return `Hello, ${name}!`;
}
console.log(schema.validate(add)); // { value: [Function: add] }
console.log(schema.validate(greet)); // { error: ... } - только 1 аргумент
Реальный практический пример: Валидация API-запроса для регистрации пользователя
Рассмотрим полно