Построение RESTful web API на платформе InterSystems — 2

Введение

Четыре года назад я написал свою первую статью на Хабре и она была посвящена созданию RESTful web API на платформе InterSystems. С тех пор прошло немало времени и вышло несколько новых релизов, которые значительно упростили работу по созданию RESTful web API. Вот об этих изменениях я и хочу рассказать в этой статье, а также дать несколько советов по созданию RESTful web API на платформе InterSystems.

Содержание

  • Архитектура RESTful web API
  • Брокеры
  • Разделение брокеров
  • Параметры брокеров
  • Обобщение кода
  • CORS
  • Аутентификация
  • Инструменты отладки и тестирования
  • Примеры
  • JSON
  • Выводы
  • Ссылки

Архитектура RESTful web API

Надеюсь, что читатель знаком с тем что такое RESTful web API и основами его реализации на платформе InterSystems (доступно начиная с версии 2014.1). Этому посвящено много статей/вебинаров/обучающих курсов в частности и моя предыдущая статья. В любом случае первое с чего хотелось бы начать это общая высокоуровневая архитектура вашего приложения, включающего RESTful web API. Выглядеть она может следующим образом:

image
На этой схеме представлены основные уровни вашего решения:

Данные

Хранимые классы на платформе InterSystems.

Терминальное API

Слой взаимодействия с данными. Данные не должны изменяться иначе, чем через это API.
Методы этого API не пишут на устройство. Терминальное API может возвращать:

  • Объект
  • Статус или исключение (в зависимости от ваших предпочтений)

Web API

Преобразует входящий запрос в форму, понимаемую терминальным API и вызывает методы терминального API. Результата выполнения терминального API возвращаются клиенту.
Web API не взаимодействует с данными напрямую. Употребляю термин Web API а не RESTful web API, т.к. Web API может быть реализовано с применением иной архитектуры, например на основе протокола WebSocket который также поддерживается платформой InterSystems, о чём уже писали на Хабре и не раз.

Клиент

Как правило JavaScript (но совсем необязательно) приложение доступное конечному пользователю. Этот уровень не должен иметь прямых связей с базой данных, быть нагруженным основной бизнес-логикой и хранить состояние приложения. На этот уровень обычно выносится только простейшая бизнес-логика: интерфейс авторизации, проверка вводимых значений на допустимость и соответствие формату, несложные операции с данными (сортировка, группировка, подсчёт значений), уже загруженными на клиент.

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

Брокеры

Брокеры это классы, содержащие логику вашего RESTful web API. Они:

  • Наследуются от %CSP.REST
  • Содержит пути – сопоставления URI и вызываемых методов

Пример пути:

<Route Url="/path/:param1/:param2" Method="GET" Call="Package.Class:ClassMethod" />

Где ClassMethod – любой метод класса.

Разделение брокеров

«Физическое» разделение

Так как в RESTful web API может быть много путей – методов, один брокер скоро будет перегружен методами. Чтобы этого не произошло разделяйте брокеры на несколько классов следующим образом:
image

Где:
– Абстрактный брокер отвечает за преобразование запросов, CORS и прочие технические моменты не связанные с логикой RESTful web API.
– Брокеры 1..N собственно содержит методы, обрабатывающие запросы (вызывающие методы терминального API и возвращающие ответы терминального API клиенту).

«Логическое» разделение и версионирование

Обычно Брокеры содержит пути – сопоставления URI и вызываемых методов, но кроме путей брокеры могут «передавать» запросы друг другу. Выглядит это так:


<Map Prefix="/form" Forward="Destination.Broker"/>

Это позволяет провести разделение брокеров по предметным областям с которыми они связаны, а также обеспечить версионирование API:

image

Параметры брокеров

Вот параметры которые рекомендуется установить в брокерах вашего RESTful web API:

Parameter CONTENTTYPE = {..#CONTENTTYPEJSON};
Parameter CHARSET = "UTF-8";
Parameter UseSession As BOOLEAN = 1;

Вот за что они отвечают:

  • CONTENTTYPE – добавляет во все ответы сервера информацию о том, что ответ будет в формате JSON.
  • CHARSET – конвертирует ответ в формат UTF8.
  • UseSession – использует сессию для запросов пользователя. Подробнее об этом в разделе аутентификация.

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

Обобщение кода

Одна из проблем, часто возникающих при написании RESTful web API это копипаста кода из брокера в брокер, что создаёт большое число путей и строк кода. Для избежания этого рекомендую использовать кодогенерацию совместно с пакетом %Dictionary содержащим всю метаинформацию необходимую для написания метод-генераторов. Примером активного использования кодогенерации является библиотека RESTForms. Кроме того использование кодогенерации позволяет достичь большего единообразия вашего RESTful web API.

CORS

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

Parameter HandleCorsRequest = 1;

Что предоставит доступ с любого другого домена. Это небезопасно и поэтому надо также переопределить метод OnHandleCorsRequest, его сигнатура:

ClassMethod OnHandleCorsRequest(pUrl As %String) As %Status {}

Этот метод должен проверять Origin запроса, к примеру он должен совпадать с именем хоста веб-приложения. Для получения Origin можно использовать вот такой метод:

ClassMethod GetOrigins() As %String
{
    set url = %request.GetCgiEnv("HTTP_REFERER")
    return $p(url,"/",1,3) // get http(s)://origin.com:port
}

Аутентификация

Для того чтобы один пользователь потреблял одну лицензию и работал в рамках одной сессии нужно сконфигурировать в Портале Управления Системой ваши REST и CSP приложения так, чтобы выполнялись условия:

  1. Во всех брокерах Parameter UseSession = 1;.
  2. Все веб приложения доступны только с аутентификацией.
  3. У всех веб приложений установлен таймаут сессии (900, 3600).
  4. У всех приложений установлено одно значение GroupById.
  5. У всех приложений установлено одно значение Cookie Path.

Инструменты отладки и тестирования

Для отладки можно использовать такие внешние средства как:

  • REST клиент (например Postman) – первоочередной инструмент отладки RESTful web API позволяет сохранять и документировать запросы, форматировать JSON ответы, выполнять запросы к нескольким окружениям и предоставляет многие другие удобства для разработчика.
  • Перехватывающий прокси-сервер (например Fiddler) – позволяет перехватывать, отображать, редактировать и дублировать запросы к RESTful web API.
  • Анализатор трафика (например WireShark) – помогает в случаях битых пакетов, проблем с кодировками, необходимостью анализа удалённой системы и прочими ситуациями когда вышеназванных инструментов недостаточно.

Настоятельно не рекомендую использовать инструменты командной строки, такие как curl и wget.

Подробно внешние и внутренние средства отладки описаны в серии статей (Часть 1 – внешние средства, Часть 2 – внутренние средства) на InterSystems Developer Community.

Примеры

Приведу несколько примеров RESTful web API.

MDX2JSON и клиент DeepSeeWeb

MDX2JSON – RESTful web API предоставляет информацию о кубах, пивотах, дашбордах и многих других элементах DeepSee, в частности – результатах исполнения MDX запросов, что позволяет встраивать пользовательский интерфейс аналитического решения на DeepSee в любое современное Web или мобильное приложение. Работает начиная с версии 2014.1.
DeepSeeWeb – AngularJS приложение, предоставляющее альтернативную реализацию портала пользователя DeepSee. Может быть легко кастомизирован. Использует MDX2JSON в качестве бэкэнда. Вот пример дашборда визуализированного в DeepSeeWeb:

image

Подробная статья про DeepSee.

EnsembleWorkflow и клиент EnsembleWorkflowUI

В интеграционной платформе InterSystems есть подсистема Ensemble Workflow, позволяющая людям участвовать в автоматизированных бизнес-процессах. Ensemble Workflow RESTful web API и клиент EnsembleWorkflowUI. RESTful web API предоставляет доступ к задачам пользователя. Работает начиная с версии 2014.1. Вот так выглядит визуализация:

image

image

RESTForms

RESTForms — универсальный RESTful web API бэкэнд работы с данными на платформе InterSystems 2016.1+ для современных веб-приложений.

Вот часть путей, доступных в RESTForms:

URL Описание
info Список классов
info/all Метаинформация всех классов
info/:class Метаинформация одного класса
object/:class/:id Получить объект
object/:class/:id/:property Получить свойство объекта
object/:class Создать объект
object/:class/:id Обновить объект из динамического объекта
object/:class Обновить объект из объекта класса
object/:class/:id Удалить объект
objects/:class/:query Выполнить SQL запрос

В этом проекте активно используется обобщение кода (с помощью кодогенерации и использования пакета %Dictionary).

Доступны клиенты на Angular и React, выглядит это так:

image

JSON

JavaScript Object Notation – текстовый формат обмена данными, использующийся совместно с RESTful web API. Поддержка JSON на платформе InterSystems появилась начиная с версии 2009.2, но была значительно улучшена к версии 2016.2. Подробнее об использовании JSON можно почитать в документации.

Выводы

  • REST на сегодня – основная и общепринятая методика построения API для сети интернет
  • Предоставляя RESTful web API вы получаете возможность выбора из огромного набора технологий построения клиентских приложений, в том числе:
    • JavaScript (AngularJS, React, extJS, …)
    • Мобильные приложения (Cordova и подобные, Native)
  • Технологии InterSystems позволяют вам с лёгкостью создавать RESTful web API.

Ссылки

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *