Библиотека Joi распространяется через npm и используется в среде Node.js для декларативной валидации данных. Перед установкой требуется наличие установленного Node.js и доступного менеджера пакетов npm или yarn.
Установка через npm выполняется командой:
npm install joi
При использовании yarn:
yarn add joi
После установки пакет появляется в node_modules, а
зависимости фиксируются в package.json, что обеспечивает
воспроизводимость окружения на других машинах.
Joi поддерживает как CommonJS, так и ES Modules, что позволяет интеграцию в различные типы проектов.
const Joi = require('joi');
import Joi from 'joi';
При использовании ES Modules важно, чтобы в package.json
было указано:
{
"type": "module"
}
Основой работы Joi является схема (schema), описывающая структуру и правила проверки данных. Схема создаётся через цепочку методов, соответствующих типам данных.
Пример схемы объекта:
const schema = Joi.object({
name: Joi.string(),
age: Joi.number(),
email: Joi.string().email()
});
Каждое поле описывается отдельным валидатором, который определяет допустимый тип и ограничения.
Для проверки используется метод validate, возвращающий
результат валидации и описание ошибок при их наличии.
const result = schema.validate({
name: 'Alex',
age: 25,
email: 'alex@example.com'
});
Структура результата:
value — нормализованные данныеerror — объект ошибки при несоответствии схемыJoi позволяет изменять поведение проверки через дополнительные параметры:
const result = schema.validate(data, {
abortEarly: false,
allowUnknown: true,
stripUnknown: true
});
Ключевые опции:
abortEarly — прекращение проверки после первой
ошибкиallowUnknown — разрешение неизвестных полейstripUnknown — удаление лишних полей из результатаJoi поддерживает строгие ограничения типов и значений.
const schema = Joi.object({
age: Joi.number().integer().min(0).max(120).required(),
username: Joi.string().alphanum().min(3).max(30).required()
});
Поддерживаются цепочки ограничений:
required() — обязательное полеmin() и max() — диапазоны значенийinteger() — целые числаalphanum() — только буквы и цифрыНаиболее частое применение Joi — валидация входящих данных в API, например в приложениях на Express.
import express from 'express';
import Joi from 'joi';
const app = express();
app.use(express.json());
const schema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).required()
});
app.post('/register', (req, res) => {
const { error } = schema.validate(req.body);
if (error) {
return res.status(400).json({
message: error.details[0].message
});
}
res.status(200).send('OK');
});
Валидация выполняется до основной бизнес-логики, что снижает риск обработки некорректных данных.
Схемы можно выделять в отдельные модули для повторного использования в разных частях приложения.
// validation/userSchema.js
import Joi from 'joi';
export const userSchema = Joi.object({
username: Joi.string().min(3).required(),
email: Joi.string().email().required()
});
Импорт в других файлах:
import { userSchema } from './validation/userSchema.js';
Joi поддерживает глобальные настройки через defaults,
позволяющие централизованно задавать поведение схем.
const base = Joi.defaults((schema) => {
return schema.options({
abortEarly: false
});
});
Дальнейшие схемы создаются на основе базовой конфигурации:
const schema = base.object({
name: Joi.string().required()
});
При использовании TypeScript часто подключается пакет типов:
npm install --save-dev @types/joi
Однако в современных версиях Joi типизация встроена частично, и многие проекты обходятся без дополнительных деклараций.
Ошибки Joi имеют структурированный формат, позволяющий извлекать детали:
const { error } = schema.validate(data);
if (error) {
console.log(error.details);
}
Каждый элемент details содержит:
message — текст ошибкиpath — путь к полюtype — тип нарушения правилаJoi поддерживает сложные структуры данных с вложенными объектами и массивами.
const schema = Joi.object({
user: Joi.object({
name: Joi.string(),
contacts: Joi.array().items(Joi.string().email())
})
});
Такая модель позволяет описывать сложные JSON-структуры без дополнительной логики.
Joi позволяет создавать расширенные правила через
extend, добавляя собственные валидаторы.
const customJoi = Joi.extend((joi) => ({
type: 'positiveInt',
base: joi.number().integer(),
validate(value, helpers) {
if (value <= 0) {
return { value, errors: helpers.error('positiveInt.base') };
}
}
}));
Joi поддерживает асинхронную проверку, например при обращении к базе данных:
const schema = Joi.object({
username: Joi.string().external(async (value) => {
const exists = await checkUser(value);
if (exists) {
throw new Error('User already exists');
}
return value;
})
});
Асинхронная валидация выполняется через
validateAsync.
await schema.validateAsync(data);