Четыре года назад я написал свою первую статью на Хабре и она была посвящена созданию RESTful web API на платформе InterSystems. С тех пор прошло немало времени и вышло несколько новых релизов, которые значительно упростили работу по созданию RESTful web API. Вот об этих изменениях я и хочу рассказать в этой статье, а также дать несколько советов по созданию RESTful web API на платформе InterSystems. Надеюсь, что читатель знаком с тем что такое RESTful web API и основами его реализации на платформе InterSystems (доступно начиная с версии 2014.1). Этому посвящено много статей/вебинаров/обучающих курсов в частности и моя предыдущая статья. В любом случае первое с чего хотелось бы начать это общая высокоуровневая архитектура вашего приложения, включающего RESTful web API. Выглядеть она может следующим образом: На этой схеме представлены основные уровни вашего решения: Хранимые классы на платформе InterSystems. Слой взаимодействия с данными. Данные не должны изменяться иначе, чем через это API.
Методы этого API не пишут на устройство. Терминальное API может возвращать: Преобразует входящий запрос в форму, понимаемую терминальным API и вызывает методы терминального API. Результата выполнения терминального API возвращаются клиенту.
Web API не взаимодействует с данными напрямую. Употребляю термин Web API а не RESTful web API, т.к. Web API может быть реализовано с применением иной архитектуры, например на основе протокола WebSocket который также поддерживается платформой InterSystems, о чём уже писали на Хабре и не раз. Как правило JavaScript (но совсем необязательно) приложение доступное конечному пользователю. Этот уровень не должен иметь прямых связей с базой данных, быть нагруженным основной бизнес-логикой и хранить состояние приложения. На этот уровень обычно выносится только простейшая бизнес-логика: интерфейс авторизации, проверка вводимых значений на допустимость и соответствие формату, несложные операции с данными (сортировка, группировка, подсчёт значений), уже загруженными на клиент. Подобное разделение увеличивает конфигурируемость приложения, облегчает его отладку, поиск и исправление ошибок. По сути это трёхуровневая архитектура построения приложений. Брокеры это классы, содержащие логику вашего RESTful web API. Они: Пример пути: Где ClassMethod – любой метод класса. Так как в RESTful web API может быть много путей — методов, один брокер скоро будет перегружен методами. Чтобы этого не произошло разделяйте брокеры на несколько классов следующим образом:
 Где: Обычно Брокеры содержит пути – сопоставления URI и вызываемых методов, но кроме путей брокеры могут «передавать» запросы друг другу. Выглядит это так: Это позволяет провести разделение брокеров по предметным областям с которыми они связаны, а также обеспечить версионирование API:  Вот параметры которые рекомендуется установить в брокерах вашего RESTful web API: Вот за что они отвечают: Так как все брокеры наследуются от одного абстрактного брокера, то эти параметры достаточно указать один раз в абстрактном брокере (наследуются только параметры первого суперкласса). Одна из проблем, часто возникающих при написании RESTful web API это копипаста кода из брокера в брокер, что создаёт большое число путей и строк кода. Для избежания этого рекомендую использовать кодогенерацию совместно с пакетом %Dictionary содержащим всю метаинформацию необходимую для написания метод-генераторов. Примером активного использования кодогенерации является библиотека RESTForms. Кроме того использование кодогенерации позволяет достичь большего единообразия вашего RESTful web API. Технология современных браузеров, которая позволяет предоставить веб-странице доступ к ресурсам другого домена. Для включения доступа к вашему RESTful web API с использованием CORS добавьте в брокер параметр: Что предоставит доступ с любого другого домена. Это небезопасно и поэтому надо также переопределить метод OnHandleCorsRequest, его сигнатура: Этот метод должен проверять Origin запроса, к примеру он должен совпадать с именем хоста веб-приложения. Для получения Origin можно использовать вот такой метод: Для того чтобы один пользователь потреблял одну лицензию и работал в рамках одной сессии нужно сконфигурировать в Портале Управления Системой ваши REST и CSP приложения так, чтобы выполнялись условия: Для отладки можно использовать такие внешние средства как: Настоятельно не рекомендую использовать инструменты командной строки, такие как curl и wget.  Подробно внешние и внутренние средства отладки описаны в серии статей (Часть 1 — внешние средства, Часть 2 — внутренние средства) на InterSystems Developer Community.  Приведу несколько примеров RESTful web API. MDX2JSON — RESTful web API предоставляет информацию о кубах, пивотах, дашбордах и многих других элементах DeepSee, в частности — результатах исполнения MDX запросов, что позволяет встраивать пользовательский интерфейс аналитического решения на DeepSee в любое современное Web или мобильное приложение. Работает начиная с версии 2014.1.
DeepSeeWeb — AngularJS приложение, предоставляющее альтернативную реализацию портала пользователя DeepSee. Может быть легко кастомизирован. Использует MDX2JSON в качестве бэкэнда. Вот пример дашборда визуализированного в DeepSeeWeb:  Подробная статья про DeepSee. В интеграционной платформе InterSystems есть подсистема Ensemble Workflow, позволяющая людям участвовать в автоматизированных бизнес-процессах. Ensemble Workflow RESTful web API и клиент EnsembleWorkflowUI. RESTful web API предоставляет доступ к задачам пользователя. Работает начиная с версии 2014.1. Вот так выглядит визуализация:   RESTForms — универсальный RESTful web API бэкэнд работы с данными на платформе InterSystems 2016.1+ для современных веб-приложений.  Вот часть путей, доступных в RESTForms: В этом проекте активно используется обобщение кода (с помощью кодогенерации и использования пакета %Dictionary). Доступны клиенты на Angular и React, выглядит это так:  JavaScript Object Notation — текстовый формат обмена данными, использующийся совместно с RESTful web API. Поддержка JSON на платформе InterSystems появилась начиная с версии 2009.2, но была значительно улучшена к версии 2016.2. Подробнее об использовании JSON можно почитать в документации.