Joi для JavaScript (Node.js): полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в 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-запроса для регистрации пользователя

Рассмотрим полно

Рекомендаций