Валидация данных в Node.js с Joi: полное руководство

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

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

Начать курс

Валидация данных в Node.js с помощью Joi

В современных веб-приложениях на Node.js валидация данных — критически важный этап обработки запросов. Ошибки в данных могут привести к уязвимостям, некорректной работе или падению сервера. Одна из самых мощных и популярных библиотек для этой задачи — Joi (произносится как «джой»). Она позволяет описывать схемы данных и проверять их соответствие заданным правилам.

Что такое Joi?

Joi — это библиотека для описания схем и валидации объектов JavaScript. Она особенно популярна в экосистеме Node.js, где часто используется вместе с Express, Hapi или Fastify. Joi предоставляет простой и выразительный API для задания типов, обязательных полей, диапазонов, регулярных выражений и кастомных проверок.

Установка

Установка Joi через npm:

npm install 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 data = {
    username: 'user123',
    password: 'pass123',
    email: 'user@example.com'
};

const { error, value } = schema.validate(data);

if (error) {
    console.log('Ошибка валидации:', error.details);
} else {
    console.log('Данные корректны:', value);
}

Основные методы и правила

Joi поддерживает множество типов и модификаторов:

  • Типы данных: Joi.string(), Joi.number(), Joi.boolean(), Joi.date(), Joi.array(), Joi.object().
  • Обязательность: .required() — поле обязательно для заполнения.
  • Ограничения: .min(), .max(), .length() — для строк и массивов.
  • Регулярные выражения: .pattern(regex) — проверка по шаблону.
  • Email и URL: .email(), .uri() — встроенные валидаторы.
  • Кастомные сообщения: .messages() — замена стандартных ошибок.

Валидация вложенных объектов и массивов

Joi отлично справляется со сложными структурами:

const addressSchema = Joi.object({
    street: Joi.string().required(),
    city: Joi.string().required(),
    zip: Joi.string().pattern(/^\d{5}$/)
});

const userSchema = Joi.object({
    name: Joi.string().required(),
    age: Joi.number().integer().min(18).max(120),
    addresses: Joi.array().items(addressSchema).min(1)
});

const userData = {
    name: 'Анна',
    age: 25,
    addresses: [
        { street: 'Невский пр.', city: 'СПб', zip: '191011' }
    ]
};

const result = userSchema.validate(userData);
console.log(result.error ? result.error.details : 'OK');

Обработка ошибок

При ошибке валидации Joi возвращает объект error.details — массив с детальным описанием каждой ошибки:

if (result.error) {
    result.error.details.forEach(detail => {
        console.log(`Поле: ${detail.path.join('.')}, сообщение: ${detail.message}`);
    });
}

Использование с Express

Joi часто применяют в middleware для проверки запросов:

const express = require('express');
const Joi = require('joi');
const app = express();

app.use(express.json());

const validateUser = (req, res, next) => {
    const schema = Joi.object({
        name: Joi.string().required(),
        email: Joi.string().email().required()
    });
    const { error } = schema.validate(req.body);
    if (error) {
        return res.status(400).json({ error: error.details[0].message });
    }
    next();
};

app.post('/user', validateUser, (req, res) => {
    res.json({ message: 'User created', user: req.body });
});

app.listen(3000);

Расширенные возможности

Joi поддерживает:

  • Условную валидацию: .when() — правила зависят от значений других полей.
  • Кастомные функции: .custom

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