Как пишется json схема

  • Introduction
  • Starting the schema
  • Defining the properties
  • Going deeper with properties
  • Nesting data structures
  • References outside the schema
  • Taking a look at data for our defined JSON Schema

Introduction #

The following example is by no means definitive of all the value JSON Schema can provide. For this you will need to go deep into the specification itself – learn more at https://json-schema.org/specification.html.

Let’s pretend we’re interacting with a JSON based product catalog. This catalog has a product which has:

  • An identifier: productId
  • A product name: productName
  • A selling cost for the consumer: price
  • An optional set of tags: tags.

For example:

{
  "productId": 1,
  "productName": "A green door",
  "price": 12.50,
  "tags": [ "home", "green" ]
}

While generally straightforward, the example leaves some open questions. Here are just a few of them:

  • What is productId?
  • Is productName required?
  • Can the price be zero (0)?
  • Are all of the tags string values?

When you’re talking about a data format, you want to have metadata about what keys mean, including the valid inputs for those keys. JSON Schema is a proposed IETF standard how to answer those questions for data.

Starting the schema #

To start a schema definition, let’s begin with a basic JSON schema.

We start with four properties called keywords which are expressed as JSON keys.

Yes. the standard uses a JSON data document to describe data documents, most often that are also JSON data documents but could be in any number of other content types like text/xml.

  • The $schema keyword states that this schema is written according to a specific draft of the standard and used for a variety of reasons, primarily version control.
  • The $id keyword defines a URI for the schema, and the base URI that other URI references within the schema are resolved against.
  • The title and description annotation keywords are descriptive only. They do not add constraints to the data being validated. The intent of the schema is stated with these two keywords.
  • The type validation keyword defines the first constraint on our JSON data and in this case it has to be a JSON Object.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product in the catalog",
  "type": "object"
}

We introduce the following pieces of terminology when we start the schema:

  • Schema Keyword: $schema and $id.
  • Schema Annotations: title and description.
  • Validation Keyword: type.

Defining the properties #

productId is a numeric value that uniquely identifies a product. Since this is the canonical identifier for a product, it doesn’t make sense to have a product without one, so it is required.

In JSON Schema terms, we update our schema to add:

  • The properties validation keyword.
  • The productId key.
    • description schema annotation and type validation keyword is noted – we covered both of these in the previous section.
  • The required validation keyword listing productId.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    }
  },
  "required": [ "productId" ]
}
  • productName is a string value that describes a product. Since there isn’t much to a product without a name it also is required.
  • Since the required validation keyword is an array of strings we can note multiple keys as required; We now include productName.
  • There isn’t really any difference between productId and productName – we include both for completeness since computers typically pay attention to identifiers and humans typically pay attention to names.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    }
  },
  "required": [ "productId", "productName" ]
}

Going deeper with properties #

According to the store owner there are no free products. ;)

  • The price key is added with the usual description schema annotation and type validation keywords covered previously. It is also included in the array of keys defined by the required validation keyword.
  • We specify the value of price must be something other than zero using the exclusiveMinimum validation keyword.
    • If we wanted to include zero as a valid price we would have specified the minimum validation keyword.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    }
  },
  "required": [ "productId", "productName", "price" ]
}

Next, we come to the tags key.

The store owner has said this:

  • If there are tags there must be at least one tag,
  • All tags must be unique; no duplication within a single product.
  • All tags must be text.
  • Tags are nice but they aren’t required to be present.

Therefore:

  • The tags key is added with the usual annotations and keywords.
  • This time the type validation keyword is array.
  • We introduce the items validation keyword so we can define what appears in the array. In this case: string values via the type validation keyword.
  • The minItems validation keyword is used to make sure there is at least one item in the array.
  • The uniqueItems validation keyword notes all of the items in the array must be unique relative to one another.
  • We did not add this key to the required validation keyword array because it is optional.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    }
  },
  "required": [ "productId", "productName", "price" ]
}

Nesting data structures #

Up until this point we’ve been dealing with a very flat schema – only one level. This section demonstrates nested data structures.

  • The dimensions key is added using the concepts we’ve previously discovered. Since the type validation keyword is object we can use the properties validation keyword to define a nested data structure.
    • We omitted the description annotation keyword for brevity in the example. While it’s usually preferable to annotate thoroughly in this case the structure and key names are fairly familiar to most developers.
  • You will note the scope of the required validation keyword is applicable to the dimensions key and not beyond.
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "length": {
          "type": "number"
        },
        "width": {
          "type": "number"
        },
        "height": {
          "type": "number"
        }
      },
      "required": [ "length", "width", "height" ]
    }
  },
  "required": [ "productId", "productName", "price" ]
}

References outside the schema #

So far our JSON schema has been wholly self contained. It is very common to share JSON schema across many data structures for reuse, readability and maintainability among other reasons.

For this example we introduce a new JSON Schema resource and for both properties therein:

  • We use the minimum validation keyword noted earlier.
  • We add the maximum validation keyword.
  • Combined, these give us a range to use in validation.
{
  "$id": "https://example.com/geographical-location.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Longitude and Latitude",
  "description": "A geographical coordinate on a planet (most commonly Earth).",
  "required": [ "latitude", "longitude" ],
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "longitude": {
      "type": "number",
      "minimum": -180,
      "maximum": 180
    }
  }
}

Next we add a reference to this new schema so it can be incorporated.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Product",
  "description": "A product from Acme's catalog",
  "type": "object",
  "properties": {
    "productId": {
      "description": "The unique identifier for a product",
      "type": "integer"
    },
    "productName": {
      "description": "Name of the product",
      "type": "string"
    },
    "price": {
      "description": "The price of the product",
      "type": "number",
      "exclusiveMinimum": 0
    },
    "tags": {
      "description": "Tags for the product",
      "type": "array",
      "items": {
        "type": "string"
      },
      "minItems": 1,
      "uniqueItems": true
    },
    "dimensions": {
      "type": "object",
      "properties": {
        "length": {
          "type": "number"
        },
        "width": {
          "type": "number"
        },
        "height": {
          "type": "number"
        }
      },
      "required": [ "length", "width", "height" ]
    },
    "warehouseLocation": {
      "description": "Coordinates of the warehouse where the product is located.",
      "$ref": "https://example.com/geographical-location.schema.json"
    }
  },
  "required": [ "productId", "productName", "price" ]
}

Taking a look at data for our defined JSON Schema #

We’ve certainly expanded on the concept of a product since our earliest sample data (scroll up to the top). Let’s take a look at data which matches the JSON Schema we have defined.


  {
    "productId": 1,
    "productName": "An ice sculpture",
    "price": 12.50,
    "tags": [ "cold", "ice" ],
    "dimensions": {
      "length": 7.0,
      "width": 12.0,
      "height": 9.5
    },
    "warehouseLocation": {
      "latitude": -78.75,
      "longitude": 20.4
    }
  }

Время на прочтение
14 мин

Количество просмотров 70K

Архитектура: искусство делать излишнее необходимым.

Фредерик Кислер

Ни для кого давно уже не секрет, что для любого web-сервиса на протоколе SOAP с сообщениями в формате XML верным и проверенным временем решением является предварительная разработка XML Schema (xsd-схемы), описывающей типы данных и структуру XML сообщений. При этом подходе у разработчиков существует явное преимущество: у них есть строгие стандартизированные правила по структуре сообщений, которые заданы в схеме, число правил конечно, и они позволяют автоматизировать проверку любого нового сообщения в формате XML.

Но также известно, что язык XML потеснился языком разметки JSON (JavaScript Object Notation) в виду его большей тяжеловесности (тяжеловесности XML), а также в виду распространения архитектурного стиля REST (REpresentational State Transfer) разработки программного обеспечения для распределенных систем. Хотя сам REST-стиль не требует использования JSON (он вообще, можно сказать, ничего не требует, а «рекомендует»), но как показывает практика, чаще при разработке REST API все-таки используется JSON для описания тела сообщений.

Так вот, практика разработки REST API с JSON–сообщениями прочно вошла в жизнь ИТ в России (и не только у нас), хотя опыт при этом по описанию структуры сообщений в виде XML Schema, значительно упростивший жизнь разработчиков web-служб в свое время, упорно игнорируется в случае c JSON–сообщениями. Но не всеми, что не может не радовать.

Когда разработчики, знакомые с XML Schema, столкнулись с необходимостью каждый раз заново изобретать велосипед с разбором документов и переизобретать логику валидации, сформировался аналогичный драфт JSON Schema. Он доступен по адресу json-schema.org, а также ряд документов по истории изменений и примеров использования. И несмотря на то что он публикуется в статусе «draft», его давно уже поддерживают все популярные платформы разработки и библиотеки на разных языках.

Сама JSON Schema предоставляет меньше возможностей по структуризации сообщений, чем XML Schema. То, что легко можно описать через XML Schema, не всегда будет тривиальной задачей повторить с помощью JSON Schema, если вообще это будет возможно. Но здесь же я бы данный факт стала рассматривать и как преимущество. Почему?

Известно, что чем проще и линейнее алгоритм работы системы, тем она и надежнее, что чем проще структура документа, тем легче он для восприятия и т.д.

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

Предисловие

Итак, о чем же эта статья?

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

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

Постановка задачи

Перед тем как приступить к изучению JSON и JSON Schema, опишу задачу, на которой мы будем рассматривать все примеры далее.

Рассмотрим ролевую модель управления в организации. Предполагаем, что справочную информацию по существующей ролевой модели мы должны будем передавать в зависимые системы в сообщениях в формате JSON посредством вызова REST-сервиса.

Описание задачи:

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

Например, бухгалтер (роль) будет иметь доступ на чтение и редактирование (операции/полномочия) к расчетным листкам (ресурс) по заработной плате всех сотрудников, а у аналитика (роль), к примеру, будет доступ на чтение (операция/полномочия) только по своему расчетному листку (ресурс).

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


Рисунок 1. Представление компонентов ролевой модели

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

  1. Роль (например, менеджер, бухгалтер и т.д.).
  2. Ресурс (например, документ, объект недвижимости и т.д.).
  3. Операция/полномочия (например, прочесть, распечатать, создать и т.д.).

При описании ролевого доступа (как один из возможных вариантов) прибегают к созданию дискретной матрицы доступа на основе выделенных сущностей, например:

Таблица 1. Дискретная матрица доступов.

Далее в статье мы ознакомимся сначала с теоретической составляющей текстового формата обмена данными JSON и правилами их структурирования с помощью JSON Schema, а в качестве примеров буду приводить описание сущностей-справочников для ролей, ресурсов и операций на языке JSON и их JSON–схем в рамках нашей поставленной задачи.

JavaScript Object Notation (JSON)

JSON (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript.

Теория

Язык разметки JSON задает ограниченный набор типов данных. Для пары {“ключ”: значение} для «ключа» всегда используют тип string, для «значения» применимы типы: string, number, object (тип JSON), array, boolean (true или false) и null.


Рисунок 2. Типы данных JSON

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

Синтаксис JSON является подмножеством синтаксиса JavaScript, где:

  1. Данные записываются в виде пар {“ключ”: значение}.
  2. Данные разделяются запятыми.
  3. В фигурных скобках записываются объекты.
  4. В квадратных скобках записываются массивы.
  5. Наименования «ключей» регистрозависимы.


Рисунок 3. Синтаксис JSON

Практика

Рассмотрим пример справочника ролей, который мы будем передавать в сервисе:


Рисунок 4. Описание справочника ролей в формате json

Из примера видно, что даже несмотря на столь небольшое число базовых типов, при их комбинации мы можем создавать более сложные структуры сообщений при необходимости. Здесь, в частности, я описываю справочник ролей через объект массивов, содержащих другие объекты (на рисунке 4 выделены двумя прямоугольниками).

В табличном виде с помощью средств визуализации json-сообщений справочник может быть представлен следующим образом:


Рисунок 5. Визуализации справочника ролей в формате JSON

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

Визуальное представление, на мой взгляд, упрощает восприятие текстового описания. Аналогичную структуру зададим и для двух других справочников. Приведу ниже пример только табличного представления для справочника полномочий (операций) и ресурсов.


Рисунок 6. Визуализации справочника полномочий в формате JSON


Рисунок 7. Визуализации справочника ресурсов в формате JSON

Исходные сообщения в текстовом формате JSON для справочника ролей, ресурсов и полномочий можно скачать/просмотреть по ссылке.
Теперь перейдем к самому интересному: к изучению JSON Schema и созданию схемы под наши справочники!

JSON Schema

Теория

Поскольку схема json написана в формате JSON, она поддерживает все типы JSON плюс дополнение: тип integer, который является подтипом типа number. Сама схема является JSON-объектом и предназначена для описания данных в формате JSON. Ниже приводится схема типов данных, используемых при создании самой схемы:


Рисунок 8. Типы данных JSON Schema

Как видно из рисунка, для схемы используются все те же типы данных, а также все те же принципы синтаксиса, что и для обычного документа JSON, приведенные на рисунке 3.

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

JSON Schema позволяет:

  1. Ограничить тип данных для элементов документа JSON.
  2. В зависимости от типа проверяемых данных, также могут быть применимы дополнительные правила — «keywords», начиная с корня схемы документа и спускаясь к их дочерним элементам.

Некоторые «ключевые слова» являются чисто описательными, как например: «title», «description» и др., которые просто описывают предназначение схемы. Другие предназначены для идентификации документа: «$schema». Это ключевое слово используется для указания желаемой версии схемы. Значение этого ключевого слова должно быть строкой, представляющей URI, например: «$schema»: «json-schema.org/draft-04/schema#».

Здесь очень важно обратить внимание, что не все версии могут поддерживаться вашим инструментом работы со схемой. Но 4-й драфт поддерживают практически все. О последних изменениях (JSON Schema 2019-09 Release Notes) для разных версий можно познакомиться по ссылке json-schema.org/draft/2019-09/release-notes.html.

Остальные ключевые слова используются непосредственно для проверки документа JSON. Их мы сейчас и рассмотрим.

Таблица 2. Анализ структуры JSON Schema. Ключевые слова и их примеры использования.

Мы рассмотрели ключевые слова схемы JSON, позволяющие описать нам будущую структуру наших сообщений в формате JSON.

Здесь вы можете найти больше примеров использования ключевых слов.

Практика

При рассмотрении примеров завершенных JSON-схем мы поступим аналогично примерам работы с самими сообщениями в формате JSON. Т.е. мы будем использовать визуальное представление в древовидном и табличном виде для наших схем справочников ролей, ресурсов и полномочий (операций), а с текстом схем предлагаю ознакомиться заинтересовавшихся читателей самостоятельно в git.

Ниже приводится схема для справочника ролей.


Рисунок 9. Пример JSON Schema для справочника ролей

Как мы видим на рисунке, схема представляет собой JSON-объект и описывает наше сообщение для передачи справочника ролей в формате JSON, которое приводилось на рисунке 4. На текущем примере представлено как с помощью JSON схемы может быть описан объект массивов, состоящий из объектов.

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

К сожалению, схема всего справочника при раскрытии не поместится на экране, поэтому рассмотрим ее часть.


Рисунок 10. Пример JSON Schema справочника, объединяющего в себе справочник ролей, полномочий и ресурсов

На рисунке мы видим, что часть объектов массива справочников подключена с использованием ключевого слова «anyOf».

Также, возможно, нагляднее будет табличное представление справочника.

Рассмотрим еще одну важную особенность нашей схемы:


Рисунок 11. Пример JSON Schema справочника, объединяющего в себе справочник ролей, полномочий и ресурсов в табличном представлении

Из рисунка мы видим, что объединяющий справочник не дублирует в себе код из ранее разработанных справочников ролей, полномочий и ресурсов, а использует ключевое слово «$ref».

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

На этом мой обзор JSON и JSON Schema я завершаю. Надеюсь, что приведенный здесь материал и рассмотренные примеры, окажутся полезными при изучении возможностей JSON Sсhema.

Вместо заключения

Думаю, пора подводить итоги. Так что же применение JSON Schema в итоге нам может дать?

  1. Может упростить жизнь разработчикам и улучшить код по валидации JSON -сообщений.
    Иными словами, это упрощение поддержки и интеграции ПО.
  2. Позволит разрабатывать сервисы, прорабатывая форматы и состав данных с «заделом» на будущее развитие системы.
  3. Применить проверку документов в документо-ориентированных, объектно-ориентированных БД.
  4. JSON-Schema может помочь сэкономить время на тестировании и документировании API.
  5. Упрощение поддержки обратной совместимости API.
  6. Позволит управлять потоками данных.
  7. Гибкую валидацию при генерации JSON Schema в run-time со значениями в «enum», получаемыми на этапе выполнения программы.
    Возможно применение для конечного автомата или workflow со статусами в «enum» (пример применения от NtsDK и VolCh).
  8. JSON Schema может быть применена при реализации DTO
    (пример использования от amarkevich)

Каждый из нас сам решает, «Быть или не быть JSON Schema» в наших IT -проектах. Выше я привела список того, что я считаю ключевым преимуществом применения схем, и ради чего уже стоит задуматься о ее применении в проектах.

Возможно, читатели захотят помочь мне продолжить этот список?
Я буду признательна :)

Также приведу список ссылок, на мой взгляд, полезных для работы с JSON и JSON Schema

  1. Официальный источник с примерами использования ключевых слов схемы.
  2. Источник с большим числом примеров использования ключевых слов схемы.
  3. Официальная страница стандарта (драфта).
  4. Список релизов (полезно для понимания динамики развития стандарта).
  5. Онлайн-валидатор с возможностью выбрать нужную версию драфта JSON-Schema.
  6. Открытый репозиторий JSON Schema
  7. JSON Schema для создания динамических интерфейсов, который может создаваться самим заказчиком (по рекомендации от alemiks), а также аналоги из мира angular ngx-schema-form, AJSF (по рекомендации от anotherpit).

И ссылку на git-репозиторий, где можно ознакомиться с исходными файлами, приводимыми для ознакомления в данной статье: репозиторий с исходными файлами примеров.

Системный архитектор,
© Ирина Блажина

To follow along with this tutorial, you’ll need a MongoDB Atlas account and to download MongoDB Compass.

JSON (JavaScript Object Notation) is a simple and lightweight text-based data format. JSON Schema is an IETF standard providing a format for what JSON data is required for a given application and how to interact with it. Applying such standards for a JSON document lets you enforce consistency and data validity across similar JSON data.

.Let’s take a look at a document example with a person’s name and their indoor and outdoor hobbies.

{
  "id": 7,
  "name": "John Doe",
  "age": 22,
  "hobbies": {
        "indoor": [
            "Chess"
        ],
        "outdoor": [
            "BasketballStand-up Comedy"
        ]
    }
}

If you were to look at the above example, you would not necessarily know if id can be zero (0). You would also not know if you could leave age blank. For this reason, we need to have metadata that holds information about valid data types and the description of the keys. Additionally, JSON Schema gives you a standard way to structure the metadata.

Basic JSON Schema Example

Let’s look at an example of a JSON Schema for the above document type.

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "number"
        },
        "name": {
            "description": "Full name of the employee",
            "type": "string"
        },
        "age": {
            "description": "Age of the employee",
            "type": "number"
        },
        "hobbies": {
            "description": "Hobbies of the employee",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "List of indoor hobbies",
                        "type": "string"
                    }
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "List of outdoor hobbies",
                        "type": "string"
                    }
                }
            }
        }
    }
}

It could look daunting at first glance but we will break it down to understand further.

JSON Schema Keywords and Properties

We have different keywords that are used in the above example. The following list explains what each of these keywords mean.

  • $schema: States that this schema complies with v4 of the IETF standard
  • $id: Defines the base URI to resolve other URI references within the schema.
  • title: Describes the intent of the schema.
  • description: Gives the description of the schema.
  • type: Defines the type of data.
  • properties: Defines various keys and their value types within a JSON document.
  • minimum: Defines the minimum acceptable value for a numeric datatype.
  • items: Enumerates the definition for the items that can appear in an array.
  • minItems: Defines the minimum number of items that should appear in an array.
  • uniqueItems: Enforces if every item in the array should be unique relative to one another.
  • required: Lists the keys that are required and mandatory.

For a full list of keywords, visit json-schema.org. The link explains the keywords that you can use in your schema and their purpose.

How do I create a JSON schema?

You can use online JSON schema generators if you have a simple JSON document, then modify the schema as per the requirement of your project. Alternatively, you can build a JSON schema of your own from scratch by following the steps below

Starting the Schema

If you have already familiarized yourself with the JSON schema keywords and properties, we can jump right into starting a basic JSON schema. Lets begin with five basic keywords to define an employee.

Base Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Record of Employee",
  "description": "This document records the details of an employee",
  "type": "object"
}

In the above example, $schema links to the resource that identifies the dialect and the valid schemas written for this dialect.

$id keyword identifies the schema resource. Here are a couple of things to know about this keyword:

  • The URI in this keyword is an identifier and not necessarily a network locator.
  • It must be a string.
  • It must represent a valid URI reference that is normalized and resolves absolute URI.
  • It must not contain a non empty fragment.
  • It should not contain an empty fragment.

title keyword gives a short description of the schema and you can use the description keyword to explain more about the schema. In the above example, the title hints that this schema is about a record of an employee and the description explains that in detail.

type keyword explains the valid data type of a record. In the above example, type sets the constraint for this document and tells us that this record is an object.

JSON Schema Properties

The Entry Schema

The schema that we have used in the above section is a basic outline. Lets build on it by adding an id field to the employee record.

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "number"
        }
    }
}

We have added two sub-properties, “id.description”, stating that it is a unique identifier, and “id.type”, explaining that it is a number.

Let’s do the same for name and age — but this time, with new keywords.

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        },
        "name": {
            "description": "full name of the employee",
            "type": "string"
            "minLength":2
        },
        "age": {
            "description": "age of the employee",
            "type": "number",
            "minimum": 16
        }
    },
    "required": [
        "id"  
        "name",
        "age"
    ]
}

In the name property, we have introduced the minLength keyword to make sure that the property has at least two characters. Similarly, in the age property, we have used the minimum keyword to ensure that the age of the employee exceeds 16 everytime. It can be of type number or type integer. We have also used the required keyword to define the mandatory properties. Now, let’s take it a step further and add an object inside the employee object.

Nesting Data Structures

To add an object inside an object in JSON format, we use nested data structure. Creating subschemas for Nested objects work quite similarly to the creating schemas for root objects. You can use all the schema keywords that you used when defining the root object except for $schema and $id. They only have to be stated at the beginning of a schema.

Arrays of Things

The following example shows how we can create an object within an object that takes an array type data. Here, we will use a few new keywords in addition to the ones we have already used.

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "number"
        },
        "name": {
            "description": "name of the employee",
            "type": "string",
            "minLength":2
        },
        "age": {
            "description": "age of the employee",
            "type": "number",
            "minimum": 16
        },
        "hobbies": {
            "description": "hobbies of the employee",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "List of hobbies",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "List of hobbies",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                }
            },
            "required": [
                "indoor",
                "outdoor"
            ]
        }
    },
    "required": [
        "id",
        "name",
        "age",
        "hobbies"
    ],
 "additionalProperties": false
}

In the above example, we have defined two array fields — indoor and outdoor in the “hobbies” object. You might have noticed the items keyword. This keyword defines the properties of each item.

Similarly, minItems defines the minimum number of items that must be present in the array, maxItems defines the maximum number of items that can be present within the array uniqueItems uniquely identifies each item.

You will also see the required keyword again within the subobject. Like the required keyword in the root JSON object, the required keyword within the subobject dictates the mandatory properties within the subobjects.

Lastly, we have also introduced additionalProperties. In the above example, it is a boolean taking the value false , telling us that we can’t use any other property that isn’t listed under the properties keyword.

However, additionalProperties doesn’t necessarily have to be a boolean. It can also be an object. For example, in the schema below, this keyword is stating that any additional property that we use under this schema is required to be of type string.

"additionalProperties": { "type": "string" }

Describing Geographical Coordinates

Though the above example is limited to a use case, there are limitless uses of JSON schema. One of the areas where JSON schema can be used to validate and enforce consistency is with geographical coordinates. Because of the nature of the data, there is a high chance of accepting invalid or inconsistent data.

In the example below, we can see that coordinates are represented using numeric data types.

{
  "latitude": 58.858093,
  "longitude": 22.294694
}

But there is a limit to the value that we can use for a coordinate i.e., the values cannot be more than 90 or less than negative 90. So let’s create a JSON schema to address this scenario.

{
  "$id": "https://example.com/geographical-location.schema.json",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Longitude and Latitude Values",
  "description": "A geographical coordinate.",
  "required": [ "latitude", "longitude" ],
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "longitude": {
      "type": "number",
      "minimum": -180,
      "maximum": 180
    }
  }
}

Here you can see that we have used the minimum and maximum keyword for each property to limit the range of acceptable values. This not only resolves the issue with data validation but also ensures that incorrect values do not get through.

Using Your Schema for Validation in MongoDB Atlas

You can use $jsonSchema in a document validator to enforce the specified schema on insert and update operations in MongoDB, including in MongoDB Atlas. Since MongoDB stores the data in BSON (Binary JSON), you can easily store and retrieve all your data in JSON format.

MongoDB also lets you enforce a schema to validate your data and maintain a data structure. We will use MongoDB Atlas and MongoDB Compass to demonstrate how.

Suppose we insert the following documents into a collection named employees inside a database named mongodatabase.

Document 1

{
    "id": 7,
    "name": "John Doe",
    "age": 22,
    "hobbies": {
        "indoor": [
            "Chess"
        ],
        "outdoor": [
            "Basketball"
        ]
    }
}

Document 2

{
     "id": 8,
     "name": "Jonathon Smith",
     "age": 22
}

Document 3

{
    "id": 1,
    "name": "Jane Doe",
    "age": 25,
    "hobbies": {
        "indoor": [
            "Chess"
        ],
        "outdoor": [
            "Football"
        ]
    }
}

Connect our cluster to MongoDB Compass
We will enforce the schema from the previous section to validate these documents in MongoDB Compass.

Firstly, let’s connect our cluster with our Compass.

  • Log into MongoDB Atlas and click Clusters
  • Click on CONNECT to connect with your cluster.
  • Set up connection security by adding your IP address and creating a database user. Then select Choose a connection method.
  • Select Connect using MongoDB Compass.
  • Download MongoDB Compass if you have not already and copy the connection string.
  • Open MongoDB Compass and paste the connection string. Your connection string should look similar to this:
mongodb+srv://<username>:<password>@cluster0.9ddm0.mongodb.net/test

Replace <username> and <password> with the username and password of the database user that you created.

select mongodatabase

Now, let’s go into the mongodatabase and look at the documents inside the employees collection.

select employees

Click on the Validation tab and insert the following JSON schema to validate our documents. Begin the schema definition with $jsonSchema keyword. Because we don’t need the $id and $schema keywords to get started, we will remove them.

{
  $jsonSchema: {
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "number"
        },
        "name": {
            "description": "name of the employee",
            "type": "string",
            "minLength":2
        },
        "age": {
            "description": "age of the employee",
            "type": "number",
            "minimum": 16
        },
        "hobbies": {
            "description": "hobbies of the employee",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "List of hobbies",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "List of hobbies",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                }
            },
            "required": [
                "indoor",
                "outdoor"
            ]
        }
    },
    "required": [
        "id",
        "name",
        "age",
        "hobbies"
    ],
 "additionalProperties": false
}
}

If you have followed the steps so far, you should get the following result.
sample document validation results

As our schema requires a hobbies field in every document, the document with the id: 8 fails because it didn’t contain the required field.

You can also set additional validation rules by following the documentation on setting validation rules for your schema. To match documents that satisfy the specified JSON Schema, you can use the $jsonSchema operator. The MongoDB JSON Schema documentation is an excellent resource to get you up and running.

To learn more about MongoDB Atlas, refer to this article.

Next Steps

By now, you should understand the JSON Schema, why it is used, and how we can use it. We have certainly expanded on the concept and how you can use it with MongoDB but there is more to cover.

If you want to learn more about JSON Schema with MongoDB, we recommend you go through MongoDB’s JSON Schema validation resource. If you are interested in knowing more about JSON Schema validation generally, visit this article.

FAQs

What is JSON Schema?

What is the use of JSON Schema?

How do I create a JSON Schema?

Is JSON Schema an industry standard for defining JSON structure?

Where should I submit the $jsonSchema data?

Рассмотрим следующий JSON-документ.

{
  "artists" : [
    { 
      "artistname" : "Deep Purple",
      "formed" : "1968"
    },
    { 
      "artistname" : "Joe Satriani",
      "born" : "1956-07-15" 
    },
    { 
      "artistname" : "Maroon 5",
      "formed" : "1994" 
    }
  ]
}

В данном примере применяется разный формат даты у объектов. Кроме того, один объект использует born (указывает, когда родился исполнитель), в то время как другие используют formed (когда образовалась группа/исполнитель).

В JSON нет правил, согласно которым некоторые объекты должны использовать определённый тип данных или даже содержать одинаковые поля. Им даже не нужно содержать одинаковое количество полей. Например, мы можем добавить поле favoritecolor к одному объекту, не добавляя его к другим.

Кроме того, нет правила, согласно которому данные должны быть в заданном формате. Например, поле born может быть представлено любым из следующих способов.

"born" : "1956"
"born" : 1956
"born" : "Июль 15, 1956"
"born" : "1956-07-15"
"born" : "07/15/1956"
"born" : "15/07/1956"
"born" : "Я люблю апельсины!"
"born" : [
  {
    "albumname" : "Flying in a Blue Dream",
    "year" : "1989",
    "genre" : "Инструментальный рок"
  }, 
  {
    "albumname" : "The Extremist",
    "year" : "1992",
    "genre" : "Инструментальный рок"
  },
  {
    "albumname" : "Shockwave Supernova",
    "year" : "2015",
    "genre" : "Инструментальный рок"
  }
]
"born" : "Упс!!!"

Да, верно — «Упс!!!». Вы можете вставить туда что угодно.

Эта гибкость — одна из вещей, которая делает JSON таким простым в использовании. Но она же одновременно может вызвать проблемы, показанные выше. Многие приложения, которые читают JSON-файлы, требуют, чтобы данные были в стандартном формате. Но даже если приложения это прочитают, людям будет трудно понять, какой именно датой является «Я люблю апельсины!».

Поэтому при работе с JSON часто требуется задать ограничения для типов данных, которые могут попадать в файл. Например, чтобы все даты вводились в определённом формате, скажем, ГГГГ-ММ-ДД. Или убедиться, что пользователи вводят только число в поле возраста.

Создание схемы

Вы можете применять правила для своих JSON-файлов, создав схему, которая позволяет указать, какой тип данных может добавляться в ваши файлы. Также схема может использоваться для проверки JSON-файла, чтобы убедиться, что он содержит только правильный тип данных.

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

{ "type": "string" }

Вот пример базовой схемы JSON Schema (взят с json-schema.org).

{
  "title": "Example Schema",
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
    "age": {
      "description": "Age in years",
      "type": "integer",
      "minimum": 0
    }
  },
  "required": ["firstName", "lastName"]
}

Можете использовать эту схему для проверки правильности ввода пользователем имени и возраста.

Как видите, JSON Schema на деле является тем же JSON. Так что не всегда легко определить что перед вами: JSON Schema или обычный JSON-документ.

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

Чтобы объявить JSON Schema, используйте ключевое слово $schema.

{ "$schema": "http://json-schema.org/schema#" }

В данном примере объявляется JSON Schema, написанная для текущей версии спецификации.

Вы также можете указать явно, какую версию спецификации используете. В следующем примере объявляется JSON Schema, написанная для JSON Schema, черновая версия 4.

{ "$schema": "http://json-schema.org/draft-04/schema#" }

Для создания JSON Schema ознакомьтесь с JSONSchema.net. Это онлайн-инструмент, который автоматически генерирует JSON Schema из любого введённого вами JSON.

Последнее изменение: 11.10.2019

Архитектура: искусство делать излишнее необходимым.

Фредерик Кислер

Ни для кого давно уже не секрет, что для любого web-сервиса на протоколе SOAP с сообщениями в формате XML верным и проверенным временем решением является предварительная разработка XML Schema (xsd-схемы), описывающей типы данных и структуру XML сообщений. При этом подходе у разработчиков существует явное преимущество: у них есть строгие стандартизированные правила по структуре сообщений, которые заданы в схеме, число правил конечно, и они позволяют автоматизировать проверку любого нового сообщения в формате XML.

Но также известно, что язык XML потеснился языком разметки JSON (JavaScript Object Notation) в виду его большей тяжеловесности (тяжеловесности XML), а также в виду распространения архитектурного стиля REST (REpresentational State Transfer) разработки программного обеспечения для распределенных систем. Хотя сам REST-стиль не требует использования JSON (он вообще, можно сказать, ничего не требует, а «рекомендует»), но как показывает практика, чаще при разработке REST API все-таки используется JSON для описания тела сообщений.

Так вот, практика разработки REST API с JSON–сообщениями прочно вошла в жизнь ИТ в России (и не только у нас), хотя опыт при этом по описанию структуры сообщений в виде XML Schema, значительно упростивший жизнь разработчиков web-служб в свое время, упорно игнорируется в случае c JSON–сообщениями. Но не всеми, что не может не радовать.

Когда разработчики, знакомые с XML Schema, столкнулись с необходимостью каждый раз заново изобретать велосипед с разбором документов и переизобретать логику валидации, сформировался аналогичный драфт JSON Schema. Он доступен по адресу json-schema.org, а также ряд документов по истории изменений и примеров использования. И несмотря на то что он публикуется в статусе «draft», его давно уже поддерживают все популярные платформы разработки и библиотеки на разных языках.

Сама JSON Schema предоставляет меньше возможностей по структуризации сообщений, чем XML Schema. То, что легко можно описать через XML Schema, не всегда будет тривиальной задачей повторить с помощью JSON Schema, если вообще это будет возможно. Но здесь же я бы данный факт стала рассматривать и как преимущество. Почему?

Известно, что чем проще и линейнее алгоритм работы системы, тем она и надежнее, что чем проще структура документа, тем легче он для восприятия и т.д.

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

Предисловие

Итак, о чем же эта статья?

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

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

Постановка задачи

Перед тем как приступить к изучению JSON и JSON Schema, опишу задачу, на которой мы будем рассматривать все примеры далее.

Рассмотрим ролевую модель управления в организации. Предполагаем, что справочную информацию по существующей ролевой модели мы должны будем передавать в зависимые системы в сообщениях в формате JSON посредством вызова REST-сервиса.

Описание задачи:

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

Например, бухгалтер (роль) будет иметь доступ на чтение и редактирование (операции/полномочия) к расчетным листкам (ресурс) по заработной плате всех сотрудников, а у аналитика (роль), к примеру, будет доступ на чтение (операция/полномочия) только по своему расчетному листку (ресурс).

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


Рисунок 1. Представление компонентов ролевой модели

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

  1. Роль (например, менеджер, бухгалтер и т.д.).
  2. Ресурс (например, документ, объект недвижимости и т.д.).
  3. Операция/полномочия (например, прочесть, распечатать, создать и т.д.).

При описании ролевого доступа (как один из возможных вариантов) прибегают к созданию дискретной матрицы доступа на основе выделенных сущностей, например:

Таблица 1. Дискретная матрица доступов.

Далее в статье мы ознакомимся сначала с теоретической составляющей текстового формата обмена данными JSON и правилами их структурирования с помощью JSON Schema, а в качестве примеров буду приводить описание сущностей-справочников для ролей, ресурсов и операций на языке JSON и их JSON–схем в рамках нашей поставленной задачи.

JavaScript Object Notation (JSON)

JSON (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript.

Теория

Язык разметки JSON задает ограниченный набор типов данных. Для пары {“ключ”: значение} для «ключа» всегда используют тип string, для «значения» применимы типы: string, number, object (тип JSON), array, boolean (true или false) и null.


Рисунок 2. Типы данных JSON

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

Синтаксис JSON является подмножеством синтаксиса JavaScript, где:

  1. Данные записываются в виде пар {“ключ”: значение}.
  2. Данные разделяются запятыми.
  3. В фигурных скобках записываются объекты.
  4. В квадратных скобках записываются массивы.
  5. Наименования «ключей» регистрозависимы.


Рисунок 3. Синтаксис JSON

Практика

Рассмотрим пример справочника ролей, который мы будем передавать в сервисе:


Рисунок 4. Описание справочника ролей в формате json

Из примера видно, что даже несмотря на столь небольшое число базовых типов, при их комбинации мы можем создавать более сложные структуры сообщений при необходимости. Здесь, в частности, я описываю справочник ролей через объект массивов, содержащих другие объекты (на рисунке 4 выделены двумя прямоугольниками).

В табличном виде с помощью средств визуализации json-сообщений справочник может быть представлен следующим образом:


Рисунок 5. Визуализации справочника ролей в формате JSON

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

Визуальное представление, на мой взгляд, упрощает восприятие текстового описания. Аналогичную структуру зададим и для двух других справочников. Приведу ниже пример только табличного представления для справочника полномочий (операций) и ресурсов.


Рисунок 6. Визуализации справочника полномочий в формате JSON


Рисунок 7. Визуализации справочника ресурсов в формате JSON

Исходные сообщения в текстовом формате JSON для справочника ролей, ресурсов и полномочий можно скачать/просмотреть по ссылке.
Теперь перейдем к самому интересному: к изучению JSON Schema и созданию схемы под наши справочники!

JSON Schema

Теория

Поскольку схема json написана в формате JSON, она поддерживает все типы JSON плюс дополнение: тип integer, который является подтипом типа number. Сама схема является JSON-объектом и предназначена для описания данных в формате JSON. Ниже приводится схема типов данных, используемых при создании самой схемы:


Рисунок 8. Типы данных JSON Schema

Как видно из рисунка, для схемы используются все те же типы данных, а также все те же принципы синтаксиса, что и для обычного документа JSON, приведенные на рисунке 3.

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

JSON Schema позволяет:

  1. Ограничить тип данных для элементов документа JSON.
  2. В зависимости от типа проверяемых данных, также могут быть применимы дополнительные правила — «keywords», начиная с корня схемы документа и спускаясь к их дочерним элементам.

Некоторые «ключевые слова» являются чисто описательными, как например: «title», «description» и др., которые просто описывают предназначение схемы. Другие предназначены для идентификации документа: «$schema». Это ключевое слово используется для указания желаемой версии схемы. Значение этого ключевого слова должно быть строкой, представляющей URI, например: «$schema»: «json-schema.org/draft-04/schema#».

Здесь очень важно обратить внимание, что не все версии могут поддерживаться вашим инструментом работы со схемой. Но 4-й драфт поддерживают практически все. О последних изменениях (JSON Schema 2019-09 Release Notes) для разных версий можно познакомиться по ссылке json-schema.org/draft/2019-09/release-notes.html.

Остальные ключевые слова используются непосредственно для проверки документа JSON. Их мы сейчас и рассмотрим.

Таблица 2. Анализ структуры JSON Schema. Ключевые слова и их примеры использования.

Мы рассмотрели ключевые слова схемы JSON, позволяющие описать нам будущую структуру наших сообщений в формате JSON.

Здесь вы можете найти больше примеров использования ключевых слов.

Практика

При рассмотрении примеров завершенных JSON-схем мы поступим аналогично примерам работы с самими сообщениями в формате JSON. Т.е. мы будем использовать визуальное представление в древовидном и табличном виде для наших схем справочников ролей, ресурсов и полномочий (операций), а с текстом схем предлагаю ознакомиться заинтересовавшихся читателей самостоятельно git.

Ниже приводится схема для справочника ролей.


Рисунок 9. Пример JSON Schema для справочника ролей

Как мы видим на рисунке, схема представляет собой JSON-объект и описывает наше сообщение для передачи справочника ролей в формате JSON, которое приводилось на рисунке 4. На текущем примере представлено как с помощью JSON схемы может быть описан объект массивов, состоящий из объектов.

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

К сожалению, схема всего справочника при раскрытии не поместится на экране, поэтому рассмотрим ее часть.


Рисунок 10. Пример JSON Schema справочника, объединяющего в себе справочник ролей, полномочий и ресурсов

На рисунке мы видим, что часть объектов массива справочников подключена с использованием ключевого слова «anyOf».

Также, возможно, нагляднее будет табличное представление справочника.

Рассмотрим еще одну важную особенность нашей схемы:


Рисунок 11. Пример JSON Schema справочника, объединяющего в себе справочник ролей, полномочий и ресурсов в табличном представлении

Из рисунка мы видим, что объединяющий справочник не дублирует в себе код из ранее разработанных справочников ролей, полномочий и ресурсов, а использует ключевое слово «$ref».

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

На этом мой обзор JSON и JSON Schema я завершаю. Надеюсь, что приведенный здесь материал и рассмотренные примеры, окажутся полезными при изучении возможностей JSON Sсhema.

Вместо заключения

Думаю, пора подводить итоги. Так что же применение JSON Schema в итоге нам может дать?

  1. Может упростить жизнь разработчикам и улучшить код по валидации JSON -сообщений.

    Иными словами, это упрощение поддержки и интеграции ПО.

  2. Позволит разрабатывать сервисы, прорабатывая форматы и состав данных с «заделом» на будущее развитие системы.
  3. Применить проверку документов в документо-ориентированных, объектно-ориентированных БД.
  4. JSON-Schema может помочь сэкономить время на тестировании и документировании API.
  5. Упрощение поддержки обратной совместимости API.
  6. Позволит управлять потоками данных.

Каждый из нас сам решает, «Быть или не быть JSON Schema» в наших IT -проектах. Выше я привела список того, что я считаю ключевым преимуществом применения схем, и ради чего уже стоит задуматься о ее применении в проектах.

Возможно, читатели захотят помочь мне продолжить этот список?
Я буду признательна :)

Также приведу список ссылок, на мой взгляд, полезных для работы с JSON и JSON Schema

  1. Официальный источник с примерами использования ключевых слов схемы.
  2. Источник с большим числом примеров использования ключевых слов схемы.
  3. Официальная страница стандарта (драфта).
  4. Список релизов (полезно для понимания динамики развития стандарта).
  5. Онлайн-валидатор с возможностью выбрать нужную версию драфта JSON-Schema.
  6. Открытый репозиторий JSON Schema
  7. JSON Schema для создания динамических интерфейсов, который может создаваться самим заказчиком (по рекомендации от alemiks).

И ссылку на git-репозиторий, где можно ознакомиться с исходными файлами, приводимыми для ознакомления в данной статье: репозиторий с исходными файлами примеров.

Системный архитектор,
© Ирина Блажина

Понравилась статья? Поделить с друзьями:
  • Как пишется join
  • Как пишется jingle bells песня
  • Как пишется jingle bells на английском
  • Как пишется jeep grand cherokee
  • Как пишется jcb