JSON Schema и комментарии в JSON: что нужно знать

JSON Schema и комментарии в JSON: что нужно знать Полезное

JSON Schema — это отдельный JSON-документ, который описывает, какой должна быть структура другого JSON: какие поля обязательны, какого они типа и какие значения допустимы. Сам формат JSON структуру не проверяет — он лишь хранит данные, а схема добавляет к ним правила и позволяет автоматически ловить некорректные документы.

Вокруг темы легко запутаться в трех близких понятиях, поэтому развожу их сразу. Ниже — зачем нужна схема, ее ключевые слова type, properties, required, enum с рабочим примером и проверкой на Python, а затем отдельно — почему в обычном JSON нет комментариев и как это обходят.

JSON, JSON Schema и JSONC — это разные вещи

Три термина звучат похоже, но решают разные задачи. Путаница между ними — самая частая ошибка новичков.

Понятие Что это Пример / где встречается
JSON текстовый формат для хранения и обмена данными {"age": 30}
JSON Schema документ с правилами, которым должен соответствовать JSON {"type": "object", "required": ["age"]}
JSONC диалект JSON, разрешающий комментарии // и /* */ конфиги VS Code, tsconfig.json
JSON5 расширенный диалект: комментарии, висячие запятые, одинарные кавычки { a: 1, /* ok */ }

Ключевое различие: JSON — это данные, JSON Schema — это описание данных (тоже записанное в JSON), а JSONC и JSON5 — это варианты синтаксиса самого JSON, в которых разрешены комментарии. Дальше в статье JSON Schema и комментарии разбираю по очереди.

Зачем нужна JSON Schema

Когда сервисы обмениваются JSON, каждый ожидает данные в определенной форме: обязательное поле id, число вместо строки, дата в нужном формате. Без проверки ошибка всплывет уже в работающем коде — в неожиданном месте и с непонятным сообщением.

JSON Schema переносит эту проверку на вход: документ сверяется со схемой до того, как попадет в логику. Схема описывает контракт данных один раз, а валидатор применяет его в любом языке — библиотеки есть для Python, JavaScript, Java и других.

Важное уточнение про типы: в самом JSON есть только number (любое число). JSON Schema добавляет отдельное ключевое слово integer — это не новый тип данных JSON, а ограничение «число должно быть целым». Так схема бывает строже, чем формат.

Ключевые слова схемы: type, properties, required, enum

Схема — это объект, где правила задаются ключевыми словами (keywords). Четыре из них покрывают большинство базовых задач.

Ключевое слово Что задает Пример значения
type допустимый тип данных "string", "integer", "object", "array", "boolean", "null"
properties описание полей объекта и их схем {"age": {"type": "integer"}}
required список обязательных полей ["name", "age"]
enum закрытый список допустимых значений ["admin", "user", "guest"]

Есть и другие ключевые слова: minimum/maximum для чисел, minLength/pattern для строк, items для массивов, additionalProperties для запрета лишних полей. Слова title и description — описательные: они не проверяют данные, а поясняют схему для человека.

Пример схемы и валидные данные

Соберем схему для объекта «пользователь»: имя-строка обязательно, возраст — целое неотрицательное число, роль — одно из трех значений.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer", "minimum": 0 },
    "role": { "type": "string", "enum": ["admin", "user", "guest"] }
  },
  "required": ["name", "age"],
  "$comment": "role необязателен: его нет в required"
}

Поле $schema в первой строке указывает, по какой версии (draft) читать схему — здесь актуальная 2020-12. Такой документ пройдет проверку:

{ "name": "Anna", "age": 30, "role": "user" }

А вот этот — нет: значение role не входит в список enum.

{ "name": "Anna", "age": 30, "role": "boss" }

Проверка на Python: библиотека jsonschema

Валидатор — это код, который сверяет данные со схемой и сообщает, где нарушено правило. В Python для этого есть пакет jsonschema. Он не входит в стандартную библиотеку — его ставят отдельно командой pip install jsonschema, поэтому в изолированной песочнице без установки пример не запустится.

from jsonschema import validate, ValidationError

schema = {
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer", "minimum": 0},
        "role": {"type": "string", "enum": ["admin", "user", "guest"]},
    },
    "required": ["name", "age"],
}

good = {"name": "Anna", "age": 30, "role": "user"}
validate(instance=good, schema=schema)   # проходит молча, без исключения

bad = {"name": "Anna", "age": 30, "role": "boss"}
try:
    validate(instance=bad, schema=schema)
except ValidationError as e:
    print(e.message)
    # 'boss' is not one of ['admin', 'user', 'guest']

При успешной проверке validate ничего не возвращает и не печатает — это нормально. При нарушении она поднимает ValidationError, и в e.message лежит причина. Точный текст и порядок сообщения зависят от версии библиотеки, поэтому в примере оставлена только одна нарушенная проверка (enum), чтобы результат был предсказуем.

Почему в JSON нет комментариев

Стандартный JSON комментарии не поддерживает — и это осознанное решение автора спецификации Дугласа Крокфорда. Он убрал их, потому что комментарии начали использовать не для пояснений, а для указаний парсеру, что ломало совместимость.

Итог: если вставить // или /* */ в файл .json, обычный парсер выдаст ошибку разбора. Формат задуман как чистый носитель данных, где пояснениям места нет. Поэтому комментарии добавляют не в JSON, а вокруг него — через диалекты или соглашения.

Как обходят отсутствие комментариев

Есть четыре распространенных подхода. Важно не путать настоящие комментарии (которые парсер выбрасывает) с полем-заполнителем (которое остается в данных).

Способ Как выглядит Что учесть
Поле-заполнитель _comment { "_comment": "тут пояснение", "age": 30 } это валидный JSON, но не комментарий: парсер читает поле как данные, программа его игнорирует
JSONC // комментарий и /* ... */ в файле нужен парсер JSONC; так устроены конфиги VS Code
JSON5 комментарии + висячие запятые + одинарные кавычки отдельный диалект (json5.org), нужна поддержка библиотекой
$comment в схеме ключевое слово внутри JSON Schema только для авторов схемы; валидатор его не проверяет и может отбросить

Поле-заполнитель вроде _comment — единственный способ, работающий в чистом JSON без сторонних библиотек, но помнить нужно: это обычные данные внутри документа, а не игнорируемый комментарий.

Ключевое слово $comment (появилось в JSON Schema draft-07) — это не способ комментировать данные. Оно живет внутри схемы и предназначено для заметок ее авторам; валидаторы его не обрабатывают и не обязаны показывать пользователю.

Выводы

  • JSON хранит данные, JSON Schema описывает и проверяет их структуру, а JSONC и JSON5 — диалекты JSON, где разрешены комментарии; это три разные сущности.
  • Базовую проверку задают ключевые слова type, properties, required, enum; integer в схеме — это ограничение «целое», а не отдельный тип JSON.
  • Валидатор (например, Python-пакет jsonschema) сверяет данные со схемой и на нарушении поднимает ValidationError с причиной.
  • В стандартном JSON комментариев нет намеренно; их заменяют полем-заполнителем _comment, диалектами JSONC/JSON5 или, внутри схемы, ключом $comment.
  • $comment относится к схеме, а не к данным, и валидатором не проверяется.

Где применяется / связь с практикой

Схемы и валидация — повседневная работа с API и конфигами: описать контракт данных, отсеять некорректный ввод, поймать ошибку до того, как она уйдет в логику. Чтобы уверенно писать такие проверки, нужна база языка — типы, словари, работа с файлами и библиотеками вроде jsonschema.

Освойте тему на практике

Освоить это с нуля помогает курс Python Basic: на нем разбирают основы языка и работу с данными, включая JSON. Посмотреть формат занятий и темы можно на открытых уроках — это бесплатно и без записи на курс.

Смежные темы: Парсинг в PHP: что нужно знать новичкам.

FAQ

Можно ли положить схему и данные в один файл?
Нет, это два независимых документа: данные проверяются отдельным валидатором по отдельной схеме. Ссылку на схему обычно хранят рядом или указывают через $schema.

Чем JSONC отличается от JSON5?
JSONC добавляет к JSON только комментарии и используется в основном в конфигах инструментов. JSON5 — более широкое расширение: кроме комментариев допускает висячие запятые, одинарные кавычки и незакавыченные ключи.

Отбросит ли валидатор мое поле _comment из данных?
Нет. _comment — обычное поле, оно остается в документе. Если хотите запретить любые лишние поля, добавьте в схему "additionalProperties": false.

OTUS Журнал