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

от автора

В этой статье я хотел бы рассказать о подходе от спецификации (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:

После запуска 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. С помощью этого подхода можно использовать различные инструменты для решения смежных задач, таких как генерация клиентов, юнит тестирование и многое другое.

Ссылки

ссылка на оригинал статьи https://habr.com/ru/company/intersystems/blog/548404/