Кратко

  • JSON Type Definition сопоставляет экземпляр с намеренно ограниченным структурным контрактом; принятие доказывает форму, а не истинность или полномочие.
  • Восемь взаимоисключающих форм, локальная политика неизвестных полей и два указателя ошибки сокращают скрытые расхождения реализаций.
  • После схемы отдельно проверяются отправитель, разрешение, правила предметной области, повтор, сохранение и фактический результат.

Правильно оформленное сообщение особенно легко принять за правильно совершённое действие. В нём есть обязательный идентификатор, разрешённая метка события и безупречная дата. Но его мог прислать посторонний, повторить после отзыва доступа или описать запись, которая так и не попала в хранилище.

JSON Type Definition из RFC 8927 не пытается ответить на эти вопросы. JTD описывает распространённые формы JSON, помогает создавать типы для обычных языков программирования и делает место ошибки переносимым между инструментами. Небольшая выразительность — сознательная цена за меньшее число разночтений.

Восемь форм и никакой тайной очередности

У JTD восемь взаимоисключающих форм: empty, ref, type, enum, elements, properties, values и discriminator. Empty принимает всё. Ref использует определение из корня. Properties описывает запись, values — словарь, discriminator — вариант, выбранный строковой меткой.

Нельзя соединить две формы и поручить библиотеке выбрать приоритет. definitions разрешены только в корне, поэтому значение ссылки не меняется на другой глубине. Ветвь discriminator не может переопределить саму метку другим типом.

Документ имеет статус Experimental и опубликован в Independent Stream. Он не выражает консенсус IETF и не относится к Standards Track. Успех эксперимента должен проявиться в нескольких независимых реализациях, реально обменивающихся информацией. Публикация RFC не является доказательством внедрения.

CDDL выражает больше и даже используется для описания синтаксиса самого JTD. Неспособность JTD описать себя соответствует цели: общий слой минимален, а не всеобъемлющ. Это практическая версия принципа Heng Lu о минимальной начальной спецификации.

Пустая схема всегда даёт зелёный свет

Форма empty принимает любой экземпляр и никогда не создаёт ошибку. Поэтому запись «JTD passed» без идентичности схемы почти бессодержательна. Проверяемый чек связывает хеш сообщения с хешем и версией схемы, сборкой валидатора, режимом и набором расширений.

metadata может хранить документацию или подсказку генератору. Другие стороны не обязаны её понимать. Если metadata меняет правила проверки, переносимое поведение возникает лишь после отдельного соглашения. Торжественное имя аннотации не делает её общим законом.

Результат описывает отношение между сообщением и исполненным контрактом. Он не создаёт реальность, о которой сообщает текст.

Открытая оболочка не открывает вложение

Properties разделяет обязательные и необязательные поля, а неизвестные по умолчанию отвергает. additionalProperties:true разрешает их только в данном объекте и не наследуется вложенными объектами.

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

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

Два адреса не задают приоритет

Стандартная ошибка содержит instancePath к отвергнутому значению и schemaPath к отвергнувшему правилу. Оба записаны как JSON Pointer. Пара позволяет воспроизвести столкновение данных и контракта.

Порядок ошибок не определён. Первый элемент не обязательно причина, наиболее тяжёлый дефект или раннее событие. Указатель на место также не даёт права исправлять данные. Для автоматического ремонта нужна отдельная политика с владельцем и откатом.

Верный формат времени не заверяет часы

JTD различает логические значения, строки, числа с плавающей точкой, целые со знаком и без знака от 8 до 32 бит и timestamps. Время соответствует RFC 3339 с уточнением Atom. Грамматика стандартизует запись, но не удостоверяет часы и событие.

Типы int64 и uint64 намеренно отсутствуют: разные среды JSON не сохраняют весь диапазон без потерь. I-JSON указывает меньший безопасный диапазон. JTD предпочитает не давать обещание, которое привычное имя типа сделало бы ложным.

Discriminator тоже лишь выбирает ветвь. Метка account_deleted требует нужные поля, но не доказывает удаление. Аутентификация, разрешение, принятие команды, долговременная запись и последующее чтение — разные чеки.

Схема может быть враждебной работой

Ссылки способны образовать цикл. RFC 8927 советует обнаруживать и прерывать циклы в пользовательских схемах, иначе наивный обход превращается в отказ в обслуживании. RFC 8259 допускает ограничения размера, глубины и точности чисел.

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

Источники

  1. RFC 8927 — JSON Type Definition
  2. RFC 8259 — Формат обмена JSON
  3. RFC 7493 — Формат I-JSON
  4. RFC 6901 — JSON Pointer
  5. RFC 3339 — Дата и время в Интернете
  6. RFC 4287 — Формат синдикации Atom
  7. RFC 8610 — Concise Data Definition Language
  8. Heng Lu — Running-Code Primacy
  9. Heng Lu — Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption
  10. Heng Lu — On Reality Layers, Symbolic Power, and Why Clarity Feels So Hostile