Библиотека Ajv строится вокруг концепции экземпляра валидатора. Именно экземпляр определяет базовое поведение всей системы валидации и задаёт глобальные правила обработки схем.
Создание экземпляра выглядит как отправная точка конфигурации:
import Ajv from "ajv";
const ajv = new Ajv({
strict: true,
allErrors: true,
removeAdditional: false,
useDefaults: true
});
Каждый параметр здесь формирует базовый слой поведения:
strict — включает строгую проверку схем JSON Schema
и выявляет потенциальные ошибки проектирования.
allErrors — заставляет валидатор собирать все ошибки, а
не останавливаться на первой. removeAdditional —
управляет удалением лишних полей. useDefaults —
активирует подстановку значений default из схемы.
На этом уровне формируется фундамент, который будет наследоваться всеми последующими операциями.
Следующий уровень конфигурации связан с компиляцией конкретной схемы.
При вызове compile или validate можно задать
поведение, отличное от глобального экземпляра.
const validate = ajv.compile({
type: "object",
properties: {
name: { type: "string" }
}
}, {
removeAdditional: "all"
});
Параметры компиляции позволяют:
Это особенно важно в системах, где разные части API требуют разных правил валидации, но используют один общий экземпляр Ajv.
JSON Schema поддерживает расширения через ключи, которые Ajv интерпретирует как директивы поведения. Эти директивы создают ещё один слой конфигурации — внутри самой схемы.
Пример:
{
"type": "object",
"properties": {
"age": {
"type": "integer",
"minimum": 18,
"default": 18
}
},
"required": ["age"]
}
Здесь default работает только при включённом
useDefaults на уровне экземпляра. Таким образом возникает
зависимость уровней:
Дополнительно используются расширения через кастомные ключи:
ajv.addKeyword({
keyword: "range",
validate: function (schema, data) {
return data >= schema.min && data <= schema.max;
}
});
Теперь схема может содержать:
{
"range": { "min": 10, "max": 20 }
}
Это уже третий уровень конфигурации — поведение через расширение языка схем.
Ajv поддерживает подключение модулей, которые влияют на поведение всех последующих схем.
Примеры расширений:
ajv-formats)ajv-errors)import addFormats from "ajv-formats";
addFormats(ajv);
После подключения:
{
"type": "string",
"format": "email"
}
Формат становится частью глобального контекста экземпляра.
Модули работают как надстройки над базовым экземпляром и формируют ещё один слой конфигурации, который нельзя переопределить локально без отключения самого расширения.
При сложных системах часто используется несколько экземпляров Ajv, каждый из которых обслуживает отдельный домен:
const publicAjv = new Ajv({ strict: false });
const internalAjv = new Ajv({ strict: true });
Это создаёт конфигурационные профили:
Каждый экземпляр имеет собственный набор:
Такая изоляция позволяет избежать конфликтов между подсистемами.
Ajv поддерживает $ref, что добавляет ещё один уровень
конфигурации — ссылочный.
{
"$ref": "#/definitions/address"
}
или внешние схемы:
ajv.addSchema(schema, "base");
{
"$ref": "base#/definitions/user"
}
Таким образом формируется иерархия:
Изменение базовой схемы автоматически влияет на все зависимые, создавая каскадный эффект конфигурации.
Ошибки в Ajv не просто результат, а конфигурируемая система.
const ajv = new Ajv({
allErrors: true,
verbose: true
});
Дополнительные модули позволяют расширять поведение:
Слой ошибок работает параллельно с валидацией, но подчиняется конфигурации экземпляра и схемы одновременно.
Механизм $data добавляет зависимость значений от других
полей:
{
"properties": {
"min": { "type": "integer" },
"value": {
"type": "integer",
"minimum": { "$data": "1/min" }
}
}
}
Это создаёт динамический слой конфигурации, где схема перестаёт быть статической и начинает зависеть от входных данных.
Для работы требуется включение:
const ajv = new Ajv({ $data: true });
При выполнении валидации действует строгая иерархия:
$dataКаждый нижележащий уровень может уточнять поведение верхнего, но не обязан его полностью переопределять.
В реальных системах конфигурация Ajv редко остаётся плоской. Обычно используется многоуровневая модель:
$dataТакой подход позволяет:
Многоуровневая конфигурация в Ajv фактически превращает JSON Schema из статического описания в управляемую систему правил, где каждый уровень отвечает за свою область ответственности и может эволюционировать независимо от остальных.