Обновить

База, которую нужно знать про JSON Schema

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели103K
Всего голосов 35: ↑30 и ↓5+33
Комментарии14

Комментарии 14

Теперь важный момент — как использовать все эти описания на практике? Ведь написать красивую схему — это только полдела. Нужно её еще и применить для валидации данных.

Я думал сейчас про Pydantic речь пойдёт, а нет...

К сожалению, база в случае с Json Schema это то, что она все ещё не является общеупотребительным стандартом и используют ее достаточно редко.

Я за 6ть лет промышленного программирования от самописов до битрикс24 вообще ни разу не встретил её использование. А работаю в основном с маркетплейсами, где данных и обмена всякого мама упаси меня.

а каким стандартом пользуетесь?

Если нужно, чтобы одно из нескольких условий было выполнено, используй anyOf. Например, хочется, чтобы поле могло быть либо числом, либо строкой...

С oneOf всё жестче — валидируется только одно из условий

Объясните разницу между AnyOf и OneOf. Пока что сложилось впечатление, что при AnyOf допустимо выполнение всех условий, а при OneOf одно условие должно выполняться, а все остальные - не выполняться (как XOR). Но примеры в статье как будто о другом.

anyOf:

Предположим, у нас есть объект, который может быть либо человеком с именем и возрастом, либо автомобилем с маркой и моделью. Мы можем использовать anyOf, чтобы разрешить объекту быть либо человеком, либо автомобилем, либо даже содержать атрибуты обоих, если это необходимо.

{
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "age": { "type": "integer" }
      },
      "required": ["name", "age"]
    },
    {
      "type": "object",
      "properties": {
        "brand": { "type": "string" },
        "model": { "type": "string" }
      },
      "required": ["brand", "model"]
    }
  ]
}

В этом примере объект будет валидным, если он является либо человеком (с именем и возрастом), либо автомобилем (с маркой и моделью), либо даже если он содержит все четыре атрибута.

  1. oneOf:

Теперь рассмотрим тот же сценарий, но с использованием oneOf. Здесь объект должен быть либо человеком, либо автомобилем, но не может быть обоими одновременно.

{
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "age": { "type": "integer" }
      },
      "required": ["name", "age"]
    },
    {
      "type": "object",
      "properties": {
        "brand": { "type": "string" },
        "model": { "type": "string" }
      },
      "required": ["brand", "model"]
    }
  ]
}

В этом случае объект будет валидным, если он является либо человеком, либо автомобилем, но не может содержать атрибуты обоих. Если объект содержит атрибуты и человека, и автомобиля, он не будет соответствовать oneOf, так как это нарушает условие соответствия только одной из схем.

Таким образом, anyOf позволяет объекту соответствовать нескольким схемам одновременно, тогда как oneOf требует, чтобы объект соответствовал только одной из указанных схем.

Допустим есть несколько полей типа Адрес. Придется для каждого поля Адрес копипастить кусок схемы. В стандарте вроде бы есть reference , но в реальной жизни использовать его невозможно, и поэтому схема превращается в ад из копипаста.

И в итоге проще валидацию сделать там же где json парсится и не возиться со схемами изучая ещё один птичий язык. И да, схема до сих пор не стандартизирована.

А в чём были сложности с использованием ссылок в JSON Schema?

А можете, пожалуйста, раскрыть, как аналитик это применяет? Он описывает схему, а разработчик её забирает в код или как-то иначе? Спасибо

У меня был опыт, когда разработчикам подают на вход какие-то разрешённые классы объектов с примерами данных, а разработчики сами под них определяют схему и создают тесты на указанных примерах. Такой TDD в некотором смысле.

В спецификации OpenAPI схемы сущностей описываются в формате JSON Schema. По крайней мере, на первый взгляд так. Соответственно, если проектируете REST API, то автоматически пользуетесь JSON Schema.

Просто получается, что это, в каком-то смысле, дублирование, потому что в итоге мы получим сваггер сгенерированный из кода разработчика и он будет дублем сваггером аналитика, который тот описал в опенапи

Почти. В OpenAPI используется синтаксис, который является надмножеством JSON Schema Specification Draft 2020-12.

"В спецификации OpenAPI схемы сущностей описываются в формате JSON Schema " .... а также можно использовать YAML, который позволяет сделать описание более компактным

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS