Построение RESTful web API на платформе InterSystems — 3: Разработка от спецификации

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

В этой статье я хотел бы рассказать о подходе от спецификации (spec-first) при разработке REST API на платформе InterSystems IRIS, который ускоряет разработку приложений в рамках микросервисной архитектуры и решение интеграционных задач. Эта статья является продолжением моей предыдущей статьи про разработку REST API на платформе InterSystems IRIS.


В то время как традиционная разработка REST API (от кода, code-first) включает:


  • Написание кода
  • Написание REST-брокера
  • Документирование REST API

При написании REST API от спецификации будeт все те же шаги, но в обратном порядке. Начинаем с написания спецификации, которая также и документация, генерируем из нее REST приложение и, наконец, пишем код бизнес-логики.


Это удобно, потому что:
  • Увеличивается скорость разработки — так как большая часть кода генерируется автоматически, вам не придется его писать, осталось только разработать бизнес-логику.
  • Более быстрые циклы обратной связи — потребители API могут сразу же получить представление об API, и им будет проще вносить предложения, просто модифицируя спецификацию.
  • Теперь у вас в файле формате Open API или на портале IAM всегда есть актуальная документация для разработчиков, использующих ваше REST API.
  • Улучшается архитектура API. При написании API от кода разработчик может легко потерять контроль над общей архитектурой API, однако при разработке от спецификации разработчик вынужден взаимодействовать с API с позиции потребителя API, что обычно помогает в проектировании архитектуры.
  • Спецификации Open API (Swagger), могут быть импортированы в различные инструменты, такие как: генераторы клиентов/серверов, управление API, юнит-тестирование и многое другое.

Давайте разработаем наше API начиная от спецификации!


План


  1. Создание спецификации
    • В Docker
    • Локально
    • Онлайн
  2. Загрузка спецификации в InterSystems IRIS
    • API Management REST API
    • Рутина ^REST
    • Классы %REST
  3. Что произошло со спецификацией?
  4. Бизнес-логика
  5. Дальнейшая разработка
  6. Особенности
    • Параметры
    • CORS
  7. Загрузка спецификации в InterSystems API Manager
  8. Дополнительные инструменты

Создание спецификации


Первое что нужно сделать — это написать спецификацию. InterSystems IRIS поддерживает спецификацию Open API версии 2 (перевод документации Swagger):


Спецификация OpenAPI (ранее Swagger) — формат описания REST API. OpenAPI позволяет вам описать спецификацию API, включая:
  • Пути (/users) и операции над ними (GET /users, POST /users)
  • Входящие параметры операций
  • Результаты вызова операций
  • Методы аутентификации
  • Контактную информацию, лицензию, условия использования и прочую информацию.


Описание API может быть представлено в форматах YAML и JSON. Формат легко изучить, и он человеко- и машинно- читаем. Спецификация OpenAPI опубликована на GitHub: OpenAPI 2.0 Specification

Мы будем использовать редактор Swagger для написания нашего API. Существует несколько способов использования Swagger:


  • Онлайн
  • В Docker: docker run -d -p 8080:8080 swaggerapi/swagger-editor
  • Локально

После запуска Swagger откройте браузер:



В левой части Swagger вы редактируете описание API, а в правой сразу видите сгенерированную документацию и инструменты тестирования.


Загрузим нашу спецификацию (в формате YAML). Это простейшее API с одним GET запросом, возвращающим случайное число между min и max.


Спецификация Math API:


swagger: "2.0"
info:
  description: "Math"
  version: "1.0.0"
  title: "Math REST API"
host: "localhost:52773"
basePath: "/math"
schemes:
  - http
paths:
  /random/{min}/{max}:
    get:
      x-ISC_CORS: true
      summary: "Генерация случайного целого числа"
      description: "Генерация случайного целого числа между min и max"
      operationId: "getRandom"
      produces:
      - "application/json"
      parameters:
      - name: "min"
        in: "path"
        description: "Минимум"
        required: true
        type: "integer"
        format: "int32"
      - name: "max"
        in: "path"
        description: "Максимум"
        required: true
        type: "integer"
        format: "int32"
      responses:
        200:
          description: "OK"

Рассмотрим эту спецификацию поподробнее.


Начинается спецификация с базового описания нашего API и используемой версии Open API.


swagger: "2.0"
info:
  description: "Math"
  version: "1.0.0"
  title: "Math REST API"

Далее идёт адрес API (сервер, порт), протокол доступа (http, https) и корневой путь:


host: "localhost:52773"
basePath: "/math"
schemes:
  - http

Далее идут относительные пути и операции (клиент, таким образом, должен будет обращаться к нашему API по адресу http://localhost:52773/math/random/:min/:max):


paths:
  /random/{min}/{max}:

Далее идёт информация о запросе:


    get:
      x-ISC_CORS: true
      summary: "Генерация случайного целого числа"
      description: "Генерация случайного целого числа между min и max"
      operationId: "getRandom"
      produces:
      - "application/json"
      parameters:
      - name: "min"
        in: "path"
        description: "Минимум"
        required: true
        type: "integer"
        format: "int32"
      - name: "max"
        in: "path"
        description: "Максимум"
        required: true
        type: "integer"
        format: "int32"
      responses:
        200:
          description: "OK"

В спецификации представлена следующая информация о запросе:


  • x-ISC_CORS: включить CORS для данной операции (см. дальше)
  • summary and description: краткое и подробное описания
  • operationId — внутренний идентификатор операции, также это название метода с кодом в нашем классе имплементации
  • produces — формат ответа (text, xml, json)
  • parameters входные параметры (в URL или теле запроса), в нашем случае мы описываем 2 параметра — минимальную и максимальную границы для генератора случайных чисел
  • responses — список возможных ответов сервера

Как вы видите, этот формат не является особенно сложным, хотя есть еще много возможностей, вот спецификация.


Следующий шаг — экспорт спецификации в формат JSON. Перейдите в меню FileConvert and save as JSON. Спецификация должна выглядеть примерно так:


{
  "swagger": "2.0",
  "info": {
    "description": "Math",
    "version": "1.0.0",
    "title": "Math REST API"
  },
  "host": "localhost:52773",
  "basePath": "/math",
  "schemes": [
    "http"
  ],
  "paths": {
    "/random/{min}/{max}": {
      "get": {
        "x-ISC_CORS": true,
        "summary": "Генерация случайного целого числа",
        "description": "Генерация случайного целого числа между min и max",
        "operationId": "getRandom",
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "min",
            "in": "path",
            "description": "Минимум",
            "required": true,
            "type": "integer",
            "format": "int32"
          },
          {
            "name": "max",
            "in": "path",
            "description": "Максимум",
            "required": true,
            "type": "integer",
            "format": "int32"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  }
}

Загрузка спецификации в InterSystems IRIS


Теперь, когда у нас есть спецификация, мы можем сгенерировать код этого REST API в InterSystems IRIS.


Для перехода к этому этапу нам понадобятся:


  • Имя REST-приложения: пакет для нашего сгенерированного кода (math)
  • Спецификация Open API в формате JSON: мы только что создали ее на предыдущем шаге.
  • Имя WEB-приложения: базовый путь для доступа к нашему API REST (/math)

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


  1. Рутина ^%REST (Do ^%REST в интерактивной терминальной сессии), документация.
  2. Класс %REST.API (Set sc = ##class(%REST.API).CreateApplication(applicationName, spec), в неинтерактивной терминальной сессии), документация.
  3. API Management REST API, документация.

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


  • В случаях (1) и (2) в качестве спецификации можно передать динамический объект, полное имя файла или URL
  • В случаях (2) и (3) необходимо создать WEB-приложение: set sc = ##class(%SYS.REST).DeployApplication(restApp, webApp, authenticationType), в нашем случае set sc = ##class(%SYS.REST).DeployApplication("math", "/math"), значения аргумента authenticationType доступны в %sySecurity.inc, см. макросы $$$Authe*, для анонимного доступа передайте значение $$$AutheUnauthenticated (32). Если значения нет, то используется авторизация по паролю.

Что произошло со спецификацией?


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


  • Spec — хранит спецификацию в формате JSON
  • Disp — вызывается при запросах к REST API. Брокер вызывает класс имплементации REST API.
  • Impl — содержит бизнес-логику REST API. Разработчик изменяет только этот класс.

Документация этих классов.


Бизнес-логика


Изначально класс имплементации math.impl содержит только один метод, соответствующий операции GET /random/{min}/{max}:


/// Get random integer between min and max<br/>
/// The method arguments hold values for:<br/>
///     min, Minimal Integer<br/>
///     max, Maximal Integer<br/>
ClassMethod getRandom(min As %Integer, max As %Integer) As %DynamicObject
{
    //(Place business logic here)
    //Do ..%SetStatusCode(<HTTP_status_code>)
    //Do ..%SetHeader(<name>,<value>)
    //Quit (Place response here) ; response may be a string, stream or dynamic object
}

Добавим бизнес-логику и скомпилируем класс math.impl:


ClassMethod getRandom(min As %Integer, max As %Integer) As %DynamicObject
{
    quit {"value":($random(max-min)+min)}
}

И вызовем наше REST API перейдя по ссылке в браузере: http://localhost:52773/math/random/1/100


В результате с сервера должен прийти такой ответ (значение value может отличаться):


{
    "value": 45
}

Также REST API можно вызвать прямо из Swagger нажав на кнопку Try it out и заполнив форму параметров:



Поздравляю! Наше первое REST API созданное от спецификации заработало!


Дальнейшая разработка


Конечно, новое REST API не статично, необходимо добавлять новые пути, операции и так далее. Сначала разрабатывается спецификация, затем обновляется REST-приложение (команды идентичны командам создания приложения) и, наконец, пишется код. Обратите внимание, что обновление спецификации безопасно: ваш код не будет удален, даже если путь был удален из спецификации, в классе имплементации метод не будет удален. Для более глобальных изменений можно дополнительно использовать версионирование API. Модуль IAM поможет с контролем за версиями API.


Особенности


Параметры


InterSystems IRIS также работает с некоторыми дополнительными параметрами спецификацию Open API:


Название Тип данных Значение по-умолчанию Раздел Описание
x-ISC_DispatchParent classname %CSP.REST info Суперкласс для класса брокера.
x-ISC_CORS boolean false operation Включение поддержки CORS запросов.
x-ISC_RequiredResource array operation Разделенный запятыми список ресурсов и привилегий (ресурс: привелегия) необходимый для доступа к операции. Пример: ["%Development:USE"]
x-ISC_ServiceMethod string operation Имя метода класса, вызываемого для исполнения операции, по умолчанию равен operationId.

CORS


Технология современных браузеров, которая позволяет предоставить веб-странице доступ к ресурсам другого домена. Есть 3 способа добавления CORS:


  1. На уровне операции, установив параметр x-ISC_CORS равным true. В Math REST API мы пошли именно этим путём.


  2. На уровне API, установив параметр в классе имплементации:


    Parameter HandleCorsRequest = 1;

  3. (Рекомендованный) На уровне API, через собственный класс брокера (наследующийся от %CSP.REST), в котором реализована логика обработки CORS запросов. Для этого используйте параметр x-ISC_DispatchParent в вашей спецификации.



Загрузка спецификации в InterSystems API Manager


Наконец, давайте добавим нашу спецификацию в InterSystems API Manager (IAM), чтобы она была доступна для других разработчиков, для контроля потребления API и аналитики по работе API.


Если вы еще не начали работать с IAM, прочитайте эту статью и посмотрите вебинар. В статье описывается запуск IAM и добавление REST API в IAM, поэтому я пропущу эти шаги тут. Перед загрузкой спецификации API в IAM необходимо изменить параметры сервера и базового пути так, чтобы они указывали на IAM, а не на InterSystems IRIS.


Откройте портал администратора IAM и перейдите на вкладку Specs (спецификации) в соответствующем workspace.



Нажмите на кнопку Add Spec и введите название нового API (в нашем случае math). После создания новой Spec в IAM нажмите кнопку Edit и вставьте код спецификации (JSON или YAML — для IAM это не имеет значения):



Не забудьте нажать Update File.


Теперь наше API опубликовано для разработчиков. Откройте портал разработчика и нажмите кнопку Documentation в правом верхнем углу. В дополнение к трем стандартным API появился наш новый API Math:



Откройте его:



Теперь разработчики могут посмотреть документацию по нашему новому API и тут же протестировать его!


Дополнительные инструменты


В InterSystems IRIS доступны дополнительные инструменты работы с Open API спецификацией:


  1. Open API Client Gen для генерации InterSystems ObjectScript клиента для работы со внешними REST API.
  2. Openapi-definition для генерации модели данных из Open API спецификации.
  3. Генератор Swagger описания по модели данных.
  4. Парсер YAML.

Выводы


InterSystems IRIS поддерживает разработку REST API от спецификации и управление REST API. Это ускоряет создание современных приложений, в том числе и с использованием практик микросервисной архитектуры, решать интеграционные задачи. InterSystems IRIS упрощает процесс разработки REST API, а подход, основанный на разработке от спецификации, позволяет быстрее и проще управлять жизненным циклом REST API. С помощью этого подхода можно использовать различные инструменты для решения смежных задач, таких как генерация клиентов, юнит тестирование и многое другое.


Ссылки


  • OpenAPI 2.0 Specification
  • Создание REST API
  • Статья по IAM
  • Вебинар по IAM
  • Документация IAM
Источник: https://habr.com/ru/company/intersystems/blog/548404/


Интересные статьи

Интересные статьи

Привет, Хабр!Меня зовут Алексей Жуков. Более 10 лет вместе с командой разработчиков я занимаюсь созданием и дизайном приложений и интернет-платформ. В статье хочу поделит...
Приветствую всех любителей и знатоков языка программирования Python! Сегодня продолжим разбираться с темой анимаций в кроссплатформенном фреймворке для с поддержкой мультитач — Kivy ...
Всем привет! В НОРБИТ мы занимаемся SRM-решениями. Сегодня расскажем про особенный для нашей команды проект — разработку BPMS-платформы NBT. Мы не просто создали бизнес-решение для...
На последнем Zabbix Summit 2019 вместе с выходом Zabbix 4.4 был анонсирован новый Zabbix Agent 2, ключевая фишка которого — возможность написания плагинов к нему на языке Go. И многие сразу стали...
Состоялся очередной бета-релиз AvaloniaUI. В релиз вошло большое количество багфиксов, оптимизаций производительности и ряд новых возможностей. Что нового, можно узнать под катом. ...