Статьи

Роль JSON Schema в создании и развертывании вашего API

Что такое схема JSON ? Он предоставляет полный способ описания структуры и свойств любого значения JSON. Это чрезвычайно полезно при документировании запросов и ответов от любого JSON API. В этой статье мы рассмотрим его роль в цикле разработки программного обеспечения API.

Документирование форматов ответов JSON

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

Давайте посмотрим на простой ответ для API книги:

1
2
3
4
5
6
7
{
  "title": "The Art of Lying",
  "pages": 412,
  "is_fiction": true,
  "status": "published",
  "updated_at": "2017-04-12T23:20:50.52Z"
}

Мы можем описать структуру этих ответов, используя следующий документ схемы JSON:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
   
  "title": "Book",
  "description": "Describes a book in our online database",
  "type": "object",
  "properties": {
    "title": {
      "description": "The title of the book"
      "type": "string",
      "minLength": 1
    },
    "pages": {
      "type": "integer",
      "minimum": 1
    },
    "is_fiction": {
      "type": "boolean"
    },
    "updated_at": {
      "type": "string",
      "format": "date-time"
    }
  },
  "additionalProperties": false
}

Потребители нашего API найдут выше полезную ссылку на то, какие поля доступны и какие типы данных они хранят.

Чтобы сделать вещи еще более официальными, мы можем даже добавить собственный заголовок ответа, который включает ссылку на наш документ схемы. Вот пример PHP отправки собственного заголовка:

1
; rel="describedby"');

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

Документирование форматов запросов JSON

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

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

API Blueprint , RAML и Open API Spec (ранее Swagger ) являются наиболее распространенными инструментами для документирования вашего API. Все они предлагают поддержку определений схемы JSON, хотя и в разной степени.

Зарегистрируй бесплатный аккаунт Codeship

Идеальный рабочий процесс разработчика

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

  1. Один источник правды (одно место, чтобы обновить определение). Если у нас есть документы JSON Schema для каждого типа данных, участвующих в нашем API, и мы можем ссылаться на эту схему из нашего инструмента API, то мы получим единый источник правды для всех вариантов использования. Проверьте!
  2. Быстрое прототипирование. Использование любого связного инструмента API даст нам возможность быстро создавать прототипы. Такие сервисы, как Apiary, используют файлы Swagger или API Blueprint и могут выступать в роли фиктивного API! Как только вы согласитесь со схемой ответа, внешняя группа может работать над написанием кода, который отформатирует его, а внутренняя группа может работать над кодом, который будет извлекать необработанные данные и возвращать их клиенту в данный формат. Проверьте!
  3. Создать документацию. Если у нас есть хорошо структурированный документ (ы) для наших маршрутов API, включая схемы JSON для структур данных в нем, относительно легко извлечь заголовки, описания и примеры в удобочитаемую документацию (да, есть много инструментов, которые делают это). Проверьте!
  4. Проверяйте полезные данные перед их отправкой. Валидаторы JSON Schema написаны практически на каждом языке. Вы можете использовать их на стороне клиента для проверки полезной нагрузки перед ее отправкой или на стороне сервера для проверки формата перед выполнением проверки бизнес-логики. Проверьте!
  5. Протестируйте API с его документацией. Если у нас есть всеобъемлющий инструмент, который документирует каждый маршрут и метод вместе со схемой JSON ответа или полезной нагрузки, то представить себе, что итерация по определенным маршрутам и проверка того, что они принимают и / или возвращают объекты, не слишком сложны. соответствовать определенным форматам схемы JSON. Dredd — это один из пакетов NPM, который выполняет эту домашнюю работу для нас: он проверяет API по своей документации (в настоящее время он поддерживает Swagger и API Blueprint). Abao — это пакет, который выполняет эту задачу для определений RAML. Проверьте!
  6. Генерация SDK. Каждый из больших инструментов API поддерживает генерацию кода SDK для доступа к API. Проверьте!

Учитывая все эти зеленые огни, может показаться, что мы живем в стране фантазий разработчиков, где все идеально! Ну, мы «чертовски близки», как сказал Фил Стерджен в своей превосходной статье на эту тему, но мы не совсем там.

Я хотел бы отметить, что наиболее серьезные недостатки любого инструмента API связаны с тем, насколько тщательно этот инструмент реализует спецификацию схемы JSON. Это не значит, что все прекрасно и прекрасно, если инструмент API полностью реализует схему JSON. Однако следование спецификации JSON Schema позволяет избежать самых вопиющих проблем — мы можем исправить эстетику гораздо проще, чем исправить архитектурные невозможности.

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

Недостатки API Blueprint

Хотя это популярный и хорошо поддерживаемый инструмент, который позволяет вам ссылаться на схемы JSON для указания форматов запросов или ответов, он все же борется с включением нескольких файлов. Это создает серьезную проблему, когда речь идет о единственном источнике правды (пункт 1 из приведенного выше списка). Что если две или более ваших конечных точек API возвращают ответ одной и той же схемы? Если нам нужен единый источник правды, то все конечные точки должны ссылаться на один и тот же файл.

Есть обходные пути для этой проблемы — другие имеют документированные методы для использования нескольких файлов в API Blueprint . Схема JSON уже поддерживает мощное ключевое слово $ref которое может выступать в качестве оператора включения, поэтому было бы неплохо, если бы API Blueprint могла использовать эту функциональность.

RAML

RAML поддерживает включение нескольких файлов через собственную директиву !includes Includes, поэтому он может легко ссылаться на один и тот же файл схемы из нескольких мест. Он также полностью поддерживает спецификацию JSON Schema вместе со своим мощным параметром $ref , поэтому схемы могут без проблем ссылаться на подсхемы или удаленные схемы.

Большинство жалоб, которые я видел в отношении RAML, касаются стиля создания документации (пункт 3 в приведенном выше списке) или того факта, что он представлен только в YAML вместо опции JSON, обе из которых довольно поверхностны. , Различия между его структурой и Swagger’s минимальны.

Единственное, что меня смущает в RAML, так это то, что он не получил более широкого распространения. Он хорошо выполняет требования рабочего процесса нашего идеального разработчика.

Swagger и его ограничения

Что бы там ни было, у Swagger есть фактор бедра, поэтому кажется, что ветер дует там. Однако он страдает от нескольких бессмысленных ограничений, которые (как вы уже догадались) связаны с отсутствием поддержки стандарта JSON Schema.

Сразу же, если у вас есть совершенно четкие и 100-процентно действительные документы JSON Schema, которые описывают все в вашем API, Swagger не будет работать . Правильно: Swagger 2.0 поддерживает только некоторые (но не все) ключевые слова JSON Schema, а Open API 3.0 (следующая итерация Swagger) не гарантирует устранения всех недостатков. Он пытается реализовать некоторые функции схемы JSON, которые существуют уже много лет, не говоря уже о более новых, которые запланированы на скорый выпуск.

Поскольку JSON Schema существует уже долгое время, было бы справедливо сказать, что Swagger не делает большую работу по уважению своих старших. Спецификация Swagger (и его замена Open API) была полностью описана в документе JSON Schema , поэтому кажется неэффективным изобретать колесо, когда оно явно не катится. Почему, например, мы должны полагаться на темпераментного онлайн-редактора для проверки наших схем?

Давайте установим несколько предупреждающих флагов, чтобы вы знали о некоторых минах. Например, Swagger не позволит вашим схемам объявлять, в какую версию схемы JSON они были написаны. Это делается с помощью ключевого слова $schema , но Swagger не поддерживает его.

Другим болезненным недостатком является то, что Swagger еще не поддерживает концепцию полей, допускающих обнуляемость. На языке схемы JSON поле может быть определено как массив типов, например, {"type": ["string", "null"]} , чтобы указать строку, допускающую обнуляемость. Если Swagger встретит это совершенно правильное соглашение JSON Schema, он захлебнется. Нехорошо!

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

Еще одним недостатком является отсутствие поддержки свойства «id» (или «$ id») схемы. На языке схемы JSON идентификатор схемы действует в некоторой степени как пространство имен, так что ссылочные схемы могут быть правильно поняты как подсхемы под родительским зонтиком или как независимые определения. Так что, если ваша ссылочная схема использует $ref для указания на другую схему, будьте осторожны! Swagger может не одобрить. Это может очень затруднить распространение ваших определений по нескольким файлам. Кажется, что Swagger предпочитает, чтобы все повторно используемые определения сохранялись в объекте definitions корневого документа, но это вряд ли практично при работе с многофайловой установкой.

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

В конце концов, вы можете заставить Swagger работать на вас, но вы должны действовать в рамках его ограничений. Как минимум, это означает порчу ваших документов JSON Schema, а иногда это означает, что нужно идти до произвольных ограничений, которые могут не совсем точно описывать ваш API. Мы рискуем столкнуться с пунктами 3, 4 и 5 из нашего священного списка.

Сохранение определений API с течением времени

Независимо от того, какой инструмент API вы используете для разработки своего API, в конечном итоге вам придется его поддерживать. Эта задача обычно проще, когда ваши определения распределены по нескольким файлам. RAML поддерживает это легко, и Swagger может сделать это с некоторыми оговорками.

Смотрите эту статью о разделении определения Swagger на несколько файлов . Во время моих исследований я создал репозиторий Github с несколькими многофайловыми примерами Swagger, которые вы можете найти в качестве полезного справочника.

Тестирование вашего API

Пока ваш инструмент API определяет маршруты и методы вашего приложения, достаточно просто выполнить итерации по ним и нажать эти конечные точки, чтобы убедиться, что они делают то, что говорят. Как упоминалось ранее, Dredd и Abao — это два пакета NPM, которые выполняют эту утомительную задачу. Основная цель — легко убедиться, что ваш API выполняет то, что вы ожидаете, и это также отличное место для начала, если вы работаете с разработкой на основе тестирования (TDD или BDD).

Резюме

Я мог бы потратить некоторое время на размышления о вероятности гибели RAML или API Blueprint, поскольку Swagger кажется настолько популярным, но на самом деле, ни одно из решений полностью не выполняет то, что я хочу как разработчик (пока).

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

Опубликовано на Java Code Geeks с разрешения Эверетта Гриффитса, партнера нашей программы JCG . См. Оригинальную статью здесь: Роль JSON Schema в создании и развертывании вашего API

Мнения, высказанные участниками Java Code Geeks, являются их собственными.