В библиотеке Joi ключевая роль отводится механизмам проверки данных,
которые позволяют описывать схемы и применять их к входящим значениям.
Среди наиболее используемых методов выделяются validate,
attempt и assert. Несмотря на общую цель —
валидацию, каждый из них отличается поведением, уровнем строгости и
способом обработки ошибок.
Метод validate является базовым инструментом проверки
данных. Он выполняет сравнение входного значения со схемой и возвращает
результат без прерывания выполнения программы.
Joi.validate(value, schema, [options], [callback])
Современные версии чаще используют:
schema.validate(value, options)
Результат работы validate представляет собой объект:
value — преобразованное и валидированное значениеerror — объект ошибки (если валидация не прошла)warning (в некоторых конфигурациях) —
предупрежденияimport Joi from 'joi';
const schema = Joi.object({
username: Joi.string().min(3).max(30),
age: Joi.number().integer().min(0)
});
const result = schema.validate({
username: 'alex',
age: 25
});
Если данные не соответствуют схеме, метод не выбрасывает исключение,
а возвращает его в поле error.
const result = schema.validate({
username: 'a',
age: -5
});
if (result.error) {
console.log(result.error.details);
}
Метод поддерживает конфигурацию поведения:
abortEarly: false — возвращает все ошибки сразуconvert: true — преобразует типы (например, строки в
числа)allowUnknown: true — разрешает неизвестные поляstripUnknown: true — удаляет лишние поляschema.validate(data, { abortEarly: false, convert: true });
Метод attempt выполняет валидацию с более строгой
моделью поведения. В случае ошибки он сразу выбрасывает исключение, а не
возвращает объект результата.
attempt используется там, где необходимо гарантировать
корректность данных до продолжения выполнения логики.
schema.attempt(value, [options])
const schema = Joi.object({
id: Joi.number().integer().required(),
name: Joi.string().required()
});
const data = schema.attempt({
id: 10,
name: 'product'
});
Если данные корректны, возвращается валидированное значение. Если нет — выполнение прерывается исключением.
schema.attempt({
id: 'wrong',
name: 'product'
});
В этом случае будет выброшено исключение, содержащее информацию о несоответствии схемы.
validate возвращает результат с ошибкойattempt выбрасывает исключениеattempt не требует проверки
if (error)try {
const result = schema.attempt(input);
} catch (err) {
console.error(err.message);
}
Метод assert представляет собой наиболее строгий вариант
проверки. Он используется для гарантии того, что данные соответствуют
схеме, и выбрасывает исключение при несоответствии без возврата
результата.
schema.assert(value, [message], [options])
const schema = Joi.object({
email: Joi.string().email().required()
});
schema.assert({
email: 'test@example.com'
});
Если значение корректно, выполнение продолжается без возврата результата.
schema.assert({
email: 'invalid-email'
});
Выбрасывается исключение с описанием ошибки валидации.
schema.assert(
{ email: 'invalid' },
'Некорректные входные данные'
);
При ошибке будет использовано указанное сообщение вместо стандартного.
| Характеристика | assert | attempt |
|---|---|---|
| Возврат значения | нет | да |
| Исключение при ошибке | да | да |
| Возможность кастомного сообщения | да | ограниченно |
| Использование результата | отсутствует | присутствует |
validate — мягкая проверкаattempt — строгая проверка с возвратом результатаassert — строгая проверка без возврата результатаvalidate — ручная обработка через объект
результатаattempt — автоматическое исключениеassert — автоматическое исключение без результатаИспользуется при необходимости собрать все ошибки и обработать их вручную.
Используется при необходимости сразу получить валидированные данные или прервать выполнение.
Используется при необходимости гарантировать корректность данных без дальнейшей обработки результата.
Все три метода работают поверх одной и той же схемы Joi. Это означает, что:
Опции схемы влияют на все методы одинаково:
stripUnknown влияет на финальный объектconvert изменяет типы входных данныхpresence управляет обязательностью полейabortEarly влияет только на validateВо всех трёх методах ошибки имеют унифицированную структуру:
message — текст ошибкиdetails — массив описаний конкретных нарушенийpath — путь к полю, где произошла ошибкаtype — тип нарушения правилаВ серверной разработке методы распределяются по слоям архитектуры:
validate — API слой (обработка запросов)attempt — бизнес-логика (гарантированные данные)assert — системные инварианты и конфигурацииschema.validate(data);
// отсутствие проверки error приводит к некорректному состоянию
schema.attempt(data); // потенциальный runtime crash
Использование assert для пользовательских данных
приводит к резкому завершению выполнения без возможности корректной
обработки ошибок на уровне UI или API.
Логика использования методов можно представить как уровни контроля данных:
validate)attempt)assert)