JSON Schema: чем отличаются обязательное поле, null и пустая строка

Матрица required, nullable и minLength: четыре синтетических документа и проверка присутствия поля для частичного обновления.

Отсутствующая, пустая и заполненная ячейки как образ missing, null и значения

Поле может отсутствовать, присутствовать со значением null или содержать пустую строку. Это три разных документа. Если API сводит их к одному состоянию, оно может очистить значение вместо сохранения или принять неполные данные вместо ошибки.

В JSON Schema обязательность и допустимый тип задаются отдельно. required проверяет присутствие свойства; он не означает автоматически «не null» или «не пустая строка». null — самостоятельный тип, а не обозначение отсутствия. Официальное руководство JSON Schema о null.

Схема с обязательным nullable-полем

Учебный объект содержит nickname. Допустимы непустая строка или явный null, но поле обязательно:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["nickname"],
  "properties": {
    "nickname": {"type": ["string", "null"], "minLength": 1}
  }
}

Вставьте схему и один синтетический документ в JSON Schema validator Neraviko. Ожидаемая матрица правил:

Документ Соответствие Причина
{} false Нет обязательного свойства
{"nickname":null} true Поле есть, null разрешён
{"nickname":""} false Строка короче minLength
{"nickname":"Demo"} true Непустая строка

minLength ограничивает строки. Он не отменяет разрешение null из списка типов. Правила длины описаны в JSON Schema Validation 2020-12.

Этот пример не описывает политику реального профиля пользователя. Решение разрешить очистку или пустое имя принадлежит вашему продукту. Схема должна выражать принятое решение, а не выбирать его за команду.

Четыре варианта контракта

Если поле обязательно и должно всегда быть строкой, оставьте required, задайте type: "string" и при необходимости minLength. Если оно обязательно, но может быть null, используйте массив типов как выше.

Если поле необязательно, уберите его имя из required. Одного присутствия в properties недостаточно, чтобы сделать его обязательным. Это правило часто пропускают, когда копируют шаблон схемы. JSON Schema: required properties.

Необязательная строка без null — тоже полезный контракт: {} проходит, {"nickname":null} не проходит. «Необязательное» здесь означает возможность отсутствия, а не возможность подставить любое пустое значение. Добавление null в список типов меняет принимаемые документы.

Частичное обновление требует своего соглашения

В учебном API договоримся: отсутствие nickname оставляет прежнее имя, null очищает его, непустая строка заменяет. Это наше явно заданное соглашение, не общий закон всех PATCH API. Для входа такого обновления свойство будет необязательным и nullable.

Присутствие можно проверить без смешивания значений в JavaScript:

function classify(source) {
  const value = JSON.parse(source);
  if (!Object.hasOwn(value, "nickname")) return "absent";
  if (value.nickname === null) return "null";
  if (value.nickname === "") return "empty string";
  return "value";
}
for (const sample of ["{}", '{"nickname":null}',
                      '{"nickname":""}', '{"nickname":"Demo"}']) {
  console.log(classify(sample));
}

Вывод: absent, null, empty string, value, по одному состоянию на строку. Это диагностика присутствия, а не полноценная валидация схемы. Перед применением обновления приложение должно проверить тип, длину и полномочия.

Проверка вида if (!value.nickname) не подходит: она смешивает отсутствие, null, пустую строку и другие falsy-значения. В контракте обновления такое смешивание особенно опасно. Сохраните четыре отдельных синтетических случая в регрессионных тестах.

Ошибка данных и ошибка схемы

В Neraviko несовпадение со схемой возвращает valid=false и статус needs_review. Это завершённая проверка, поэтому HTTP 200 сам по себе не означает, что поле подходит. Читайте нарушения, путь данных и путь правила.

Некорректный JSON или неподдерживаемая схема — другой результат: error envelope с HTTP 422. Если схема не разбирается, исправляйте документ схемы. Если нарушено required, решите, должен ли отправитель заполнить поле, а не удаляйте правило ради успешного ответа.

Neraviko поддерживает ограниченное подмножество Draft 2020-12. Удалённые и рекурсивные ссылки не поддерживаются; обычное поле с локальным правилом выше не требует ссылок. default не следует считать приказом валидатору вставить значение: валидация проверяет данные, а политика заполнения принадлежит приложению.

Обработка данных и схемы серверная. Используйте синтетические профили, как здесь, вместо настоящих персональных сведений. Лимиты — 262 144 байта данных и 65 536 байт схемы с дополнительными общими ограничениями. Если схема проходит, это подтверждает только её правила; происхождение данных и смысл изменения должны проверяться отдельно.