
Проблема, которую 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-контрактах, конфигурационных файлах, шаблонах инфраструктуры. Но как только от неё начинают ждать понимания смысла данных, гарантии полной безопасности или автоматической совместимости при любых изменениях — иллюзия порядка начинает подменять реальную проверку. Схема — это контракт о форме, а не о содержании, и разница между этими двумя вещами часто оказывается дороже, чем кажется на этапе проектирования.


