В JSON Schema отсутствие свойства и его наличие с неопределённым
значением трактуются по-разному. Опциональность определяется через
массив required, в котором перечисляются обязательные ключи
объекта. Любое свойство, не включённое в этот список, считается
необязательным.
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"required": ["name"]
}
В данной схеме поле name обязательно, тогда как
age может отсутствовать полностью. При проверке Ajv
учитывает именно структуру объекта, а не наличие ключей со значением
undefined, поскольку в JSON такого значения не
существует.
Если свойство отсутствует, Ajv не выполняет проверку его типа. Это означает, что валидатор работает только с реально присутствующими данными. В случае частичных объектов это позволяет строить гибкие схемы для PATCH-запросов и частичных обновлений.
Особенность поведения проявляется при включённой опции
useDefaults. Тогда при наличии default в схеме
отсутствующие поля могут быть автоматически добавлены в объект:
{
"type": "object",
"properties": {
"status": {
"type": "string",
"default": "active"
}
}
}
В JSON значение null является допустимым примитивом, но
оно не входит в типы string, number,
boolean, object, array. Поэтому
для разрешения null используется расширение типа.
Основной механизм — указание массива типов:
{
"type": ["string", "null"]
}
Такое определение означает, что поле может быть строкой либо
null.
Этот подход является стандартом JSON Schema и работает во всех актуальных версиях Ajv.
В более ранних версиях Ajv поддерживался ключ nullable,
который упрощал запись:
{
"type": "string",
"nullable": true
}
При компиляции такая схема фактически преобразовывалась в объединение
типов. Однако в современных версиях предпочтение отдаётся явному
union-формату через массив типов, поскольку nullable не
является частью базовой спецификации JSON Schema.
Отсутствующее поле и поле со значением null семантически
различаются и по-разному обрабатываются валидатором.
{}
Если поле не объявлено в required, объект считается
валидным независимо от его типа.
{
"value": null
}
В этом случае проверяется соответствие схемы. Если null
не разрешён, возникает ошибка типа.
На практике часто требуется одновременно разрешить отсутствие поля и
значение null. Эти случаи не эквивалентны и описываются
отдельно.
{
"type": "object",
"properties": {
"description": {
"type": ["string", "null"]
}
}
}
Здесь:
description допустимо, если поле не входит в
requirednull допустим как одно из значенийЕсли добавить поле в required, появляется дополнительное
ограничение:
{
"type": "object",
"properties": {
"description": {
"type": ["string", "null"]
}
},
"required": ["description"]
}
Теперь поле обязательно должно присутствовать, но его значение может
быть null.
При валидации Ajv выполняет несколько последовательных шагов:
required)format, pattern, minimum)nullable или union-типовЕсли поле отсутствует и не является обязательным, дальнейшие проверки не выполняются.
Если поле присутствует со значением null, но
null не разрешён, фиксируется ошибка типа:
data.property should be string
{
"type": "object",
"properties": {
"title": { "type": "string" },
"subtitle": { "type": ["string", "null"] },
"description": { "type": "string" }
},
"required": ["title"]
}
В данной структуре:
title обязателенsubtitle может отсутствовать или быть
nulldescription полностью опционален, но если присутствует
— должен быть строкойВ API часто встречаются поля, которые могут быть не заданы на стороне сервера. В таких случаях используется комбинация:
null для явно неизвестного или отсутствующего
значения{
"type": "object",
"properties": {
"lastLogin": {
"type": ["string", "null"]
},
"phone": {
"type": "string"
}
}
}
В актуальных версиях Ajv поведение стало ближе к стандарту JSON Schema:
nullable считается устаревшим подходомstrictПри строгом режиме использование нестандартных ключей может приводить к предупреждениям или ошибкам компиляции схемы.
При обработке PATCH-запросов часто требуется различать:
null (явно очистить значение)Схема в таких случаях строится с акцентом на отсутствие
required:
{
"type": "object",
"properties": {
"email": {
"type": ["string", "null"]
},
"nickname": {
"type": "string"
}
}
}
Отсутствующие поля игнорируются валидатором, а null
проходит только при явном разрешении.
Типичные ошибки валидации возникают при смешении ожиданий:
null вместо строки без разрешения
union-типаnullable в версиях Ajv, где ключ не
поддерживаетсяКаждая из этих ситуаций приводит к различным результатам, зависящим от версии и режима строгой проверки схемы.
Валидация в Ajv опирается на формальную модель данных:
null → отдельный допустимый тип, если он явно
указанТакое разделение позволяет точно моделировать реальные API-структуры, где отсутствие данных и их неопределённость имеют разные смысловые нагрузки.