JSON Schema: невидимый контракт, без которого API держатся на честном слове

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

JSON Schema как контракт для API и данных, позволяющий валидировать структуру запросов и конфигураций

Проблема, которую JSON изначально не решал

JSON стал популярным форматом обмена данными именно из-за своей гибкости: он читается человеком, легко парсится машиной и не навязывает жёсткую структуру. Но у этой гибкости есть обратная сторона — JSON-объект может выглядеть как угодно, и сервер, ожидающий данные корзины покупок, вполне может получить платёжную транзакцию или вовсе не тот набор полей. Раньше эта проблема решалась негласно: команды писали документацию, договаривались «на словах» или в комментариях к коду, а несостыковки всплывали уже в проде.

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

Что реально делает схема

Базовый набор возможностей закрывает большинство практических задач: ключевое слово type задаёт тип верхнего уровня, properties перечисляет ожидаемые поля и их типы, required фиксирует, какие поля обязаны присутствовать. Более сложные схемы используют $ref и $defs для переиспользования фрагментов — то есть можно один раз описать структуру «адреса» и ссылаться на неё из десятков других схем, не дублируя код.

Именно на этом фундаменте построены вещи, которые многие используют, даже не подозревая об этом. Спецификация OpenAPI описывает структуру запросов и ответов HTTP API через схемы, основанные на JSON Schema. Шаблоны инфраструктуры вроде Azure Resource Manager используют JSON Schema для проверки корректности файлов конфигурации ещё до того, как они попадут в развёртывание. Иными словами, схема — это не узкоспециализированный инструмент валидации форм, а связующий слой между людьми и системами, которые должны договориться о форме данных, даже не видя код друг друга.

Но здесь важно не путать «схема описывает структуру» с «схема гарантирует правильность». Актуальный черновик спецификации прямо говорит о более широком назначении: JSON Schema задаёт не только валидацию, но и аннотации, навигацию по документу и управление взаимодействием с данными. То есть схема — это ещё и способ документировать смысл полей, помечать их как устаревшие или предназначенные только для чтения, связывать документы гиперссылками. Валидация — лишь одна из функций, пусть и самая заметная.

Где заканчивается компетенция схемы

Здесь и рождается главное недоразумение. Если схема говорит «поле email — это строка», она никак не проверяет, что это действительно рабочий email, а не случайный набор символов, соответствующий формату (если формат вообще задан и провалидирован строго). Если схема требует поле price, она ничего не знает о том, что цена не может быть отрицательной для конкретного бизнес-сценария, если разработчик не добавил это ограничение отдельно. Схема проверяет форму, а не смысл — и это разделение стоит держать в голове каждый раз, когда кто-то говорит «у нас всё провалидировано, значит, безопасно».

Что проверяет JSON Schema Что остаётся вне её поля зрения
Тип данных (строка, число, объект, массив) Смысловая корректность значения (реальный ли это email, существует ли пользователь)
Обязательные поля и их наличие Бизнес-правила (например, скидка не может превышать 100%)
Ограничения на длину строк, диапазон чисел, размер массивов Согласованность данных между разными системами во времени
Переиспользуемые фрагменты через $ref и $defs Безопасность приложения в целом (авторизация, инъекции, логика доступа)
Аннотации и документация полей (title, description, deprecated) Гарантия того, что API останется совместимым при следующем изменении

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

Как схема встраивается в реальный поток запросов

Полезно представить, в какой момент схема вообще вступает в игру — потому что часто её воспринимают как отдельный «магический» слой, а не как часть обычного цикла обработки запроса.

flowchart LR
 A[Автор описывает схему] --> B[Схема встраивается в OpenAPI]
 B --> C[Клиент отправляет запрос]
 C --> D{Валидатор проверяет структуру}
 D -->|Соответствует| E[API обрабатывает данные]
 D -->|Не соответствует| F[Запрос отклонён с ошибкой]

Схема появляется на этапе проектирования и остаётся статичным документом до тех пор, пока её явно не изменят. Валидатор — это отдельный компонент, который сверяет входящие данные с этим документом в момент запроса. Если структура не совпадает, запрос отклоняется раньше, чем доберётся до логики приложения — что и снижает вероятность падений и части атак на парсинг, но не гарантирует, что принятые данные «имеют смысл» в контексте бизнеса.

Почему версий и черновиков так много

Одна деталь часто сбивает с толку тех, кто впервые сталкивается с JSON Schema: спецификация существует не в виде одного финального документа, а в виде цепочки черновиков — Draft 3, 4, 6, 7, 2019-09, 2020-12 и далее, каждый со своими метасхемами и наборами ключевых слов. Это не хаос ради хаоса. JSON Schema развивалась как открытый проект, тесно связанный с IETF, стремясь к тому, чтобы разные организации — от OpenAPI Initiative до 3GPP и OpenBanking UK — могли использовать общий язык описания структур данных. При этом спецификация долгое время существовала только как интернет-драфты и никогда не публиковалась как полноценный RFC-стандарт; рабочая группа при IETF сейчас как раз занимается тем, чтобы собрать стабильную, «боевую» версию на основе реально используемых механизмов, а не всех теоретически возможных функций.

Новый драфт также вводит понятия vocabularies (наборов ключевых слов, которые схема явно объявляет через $vocabulary) и dialects — то есть схема теперь может явно заявлять, какой набор правил она использует, а не полагаться на молчаливое согласие всех сторон. Это усложняет картину, но и делает её честнее: вместо одной жёсткой версии — расширяемая система, где реализации могут поддерживать разные наборы возможностей, и это стоит учитывать, если схема должна работать одинаково в разных инструментах.

Совместимость — это не просто «поля на месте»

Отдельный миф — что если схема проверяет структуру, то она автоматически обеспечивает совместимость версий API или данных во времени. На практике совместимость — это отдельная дисциплина. Хороший пример — то, как схема регистрируется и проверяется в системах вроде Schema Registry для потоковых платформ: там явно разделяют backward-, forward- и full-совместимость, и для JSON Schema это поведение зависит не только от самого факта наличия схемы, но и от политики (строгой или мягкой) и от модели содержимого — открыта ли схема для дополнительных полей или закрыта. То есть один и тот же набор ключевых слов может считаться «совместимым изменением» в одной конфигурации и «ломающим изменением» в другой — это решает не JSON Schema как формат, а правила конкретной системы поверх неё.

Что из этого следует

JSON Schema — полезный инструмент именно потому, что переводит невысказанные ожидания о форме данных в проверяемые правила, а не потому, что «делает JSON правильным». Она хорошо справляется там, где команды заранее договариваются о структуре, версиях и правилах эволюции — в API-контрактах, конфигурационных файлах, шаблонах инфраструктуры. Но как только от неё начинают ждать понимания смысла данных, гарантии полной безопасности или автоматической совместимости при любых изменениях — иллюзия порядка начинает подменять реальную проверку. Схема — это контракт о форме, а не о содержании, и разница между этими двумя вещами часто оказывается дороже, чем кажется на этапе проектирования.

Источники

  1. What is a JSON Schema?
  2. JSON Schema
  3. Specification Links
  4. JSON Schema charter-ietf-jsonschema-01
  5. Schema Evolution and Compatibility for Schema Registry on Confluent Platform
Поделиться:
Telegram Facebook X VK
Scroll to Top