Библиотека Ajv предоставляет детализированную систему валидации
JSON-схем, где ключевым элементом отладки становится структура
возвращаемых ошибок. При неуспешной валидации метод
validate возвращает false, а подробности
содержатся в validate.errors.
Каждая ошибка представляет собой объект с полями:
Пример:
const validate = ajv.compile(schema);
const valid = validate(data);
if (!valid) {
console.log(validate.errors);
}
instancePath указывает на конкретное место в проверяемом объекте данных. schemaPath указывает на участок схемы, который вызвал ошибку.
Пример:
{
"instancePath": "/user/age",
"schemaPath": "#/properties/user/properties/age/minimum",
"keyword": "minimum",
"message": "must be >= 18"
}
Такая связка позволяет точно сопоставить:
Ajv поддерживает несколько режимов, влияющих на детализацию ошибок.
По умолчанию валидация может останавливаться на первой ошибке. Режим
allErrors заставляет продолжать проверку:
const ajv = new Ajv({ allErrors: true });
Это критически важно при отладке сложных схем, где необходимо видеть полный список проблем.
Строгий режим помогает выявлять ошибки в самой схеме, а не только в данных:
const ajv = new Ajv({ strict: true });
Он контролирует:
Дополнительно:
const ajv = new Ajv({
strictTypes: true,
strictTuples: true,
strictRequired: true
});
Ошибки могут возникать не только при валидации данных, но и при компиляции схемы.
try {
const validate = ajv.compile(schema);
} catch (err) {
console.error(err.message);
}
Типичные причины:
Для удобной отладки используется преобразование ошибок в строку:
import Ajv from "ajv";
const ajv = new Ajv({ allErrors: true });
const validate = ajv.compile(schema);
if (!validate(data)) {
console.log(ajv.errorsText(validate.errors));
}
Функция агрегирует ошибки в читаемый текст, но теряет структурированность.
Ajv позволяет включать расширенную информацию об ошибках:
const ajv = new Ajv({
verbose: true
});
В этом режиме добавляются дополнительные поля:
Это полезно при глубокой диагностике сложных схем.
Ajv компилирует схемы в оптимизированные функции JavaScript. Их можно исследовать:
const validate = ajv.compile(schema);
console.log(validate.toString());
Это позволяет увидеть:
При сложных схемах это часто быстрее выявляет проблему, чем анализ
errors.
Ajv поддерживает подключение логгера:
const ajv = new Ajv({
logger: console
});
Он позволяет отслеживать:
Механизм $data позволяет ссылаться на значения внутри
данных:
const schema = {
properties: {
min: { type: "number" },
value: {
type: "number",
minimum: { $data: "1/min" }
}
}
};
Ошибки в таких схемах часто связаны с:
При отладке важно проверять:
$dataПри использовании async-схем:
const validate = ajv.compileAsync(schema);
validate(data)
.then(valid => {})
.catch(err => {
console.error(err);
});
Ошибки могут быть двух типов:
Особое внимание требуется при format с асинхронной
проверкой.
Ajv позволяет добавлять кастомные ключевые слова:
ajv.addKeyword({
keyword: "even",
validate: (schema, data) => data % 2 === 0
});
При отладке важно учитывать:
errors внутри custom keywordДля диагностики полезно временно расширять валидатор:
validate.errors = [];
или добавлять логирование внутри функции validate.
Одна из наиболее частых проблем:
{ "type": "string" }
при передаче числа приводит к ошибке type.
{
"required": ["id"]
}
Отсутствие поля приводит к ошибке required.
Сложные конструкции:
oneOf требует ровно одну валидную схемуanyOf допускает несколькоОшибки часто возникают из-за перекрытия условий.
Ajv может не приводить типы автоматически:
const ajv = new Ajv({ coerceTypes: true });
Без этого числовые строки "123" будут считаться
ошибкой.
Создание экземпляра Ajv с расширенной конфигурацией облегчает локализацию ошибок:
const ajv = new Ajv({
allErrors: true,
strict: true,
verbose: true,
logger: console,
coerceTypes: false
});
Такая конфигурация делает поведение предсказуемым и максимально прозрачным для анализа схем.