Спецификация REST API сервисов MathCloud

Общая схема интерфейса

В соответствии с принципами REST, интерфейс сервиса образован совокупностью идентифицируемых при помощи URI ресурсов, поддерживающих стандартные методы протокола HTTP (Табл. 1). Данными ресурсами являются:

  • сервис, идентифицируемый с помощью SERVICE_URI;
  • задание, идентифицируемое с помощью JOB_URI;
  • файл результата задания, идентифицируемый с помощью FILE_URI;
  • сервер, идентифицируемый с помощью SERVER_URI (является необязательным ресурсом).
Ресурс GET POST DELETE
Сервис SERVICE_URI Получение описания сервиса Вызов сервиса  
Задание JOB_URI Получение статуса и результатов задания   Отмена задания, удаление данных задания
Файл FILE_URI Загрузка файла    
Сервер SERVER_URI Получение списка сервисов, предоставляемых сервером    

Ресурс-сервис поддерживает два метода. Метод GET возвращает клиенту представление данного ресурса, содержащее описание сервиса. Метод POST служит для отправки сервису нового запроса. В теле запроса клиент передает набор значений входных параметров задачи. В ответ сервис создает новый ресурс-задание, являющийся подчиненным по отношению к ресурсу-сервису, и возвращает идентификатор ресурса-задания и его текущее представление клиенту.

Ресурс-задание поддерживает методы GET и DELETE. Метод GET возвращает представление данного ресурса, содержащее информацию о текущем статусе задания.

Данная информация должна обязательно включать состояние задания, которое может принимать следующие значения:

  • WAITING — выполнение задания еще не началось;
  • RUNNING — задание выполняется;
  • DONE — задание выполнено успешно;
  • FAILED — выполнение задания завершилось ошибкой.

Если выполнение задания завершено успешно (состояние DONE), то в представление ресурса-задания также включается результат задания в виде набора значений выходных параметров. Часть значений выходных параметров может содержать идентификаторы ресурсов-файлов.

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

Метод DELETE ресурса-задания позволяет клиенту отменить выполнение запроса или, если выполнение уже завершено, удалить результаты задания. После вызова DELETE данный ресурс-задание, а также подчиненные ему ресурсы-файлы, перестают существовать.

Ресурс-файл представляет собой часть результата задания и поддерживает метод GET для получения содержимого файла клиентом.

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

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

Описанный интерфейс поддерживает обработку запросов как в синхронном, так и асинхронном режиме. Действительно, если результат запроса может быть сразу возвращен клиенту, то он передается внутри возвращаемого в ответ клиенту представления ресурса-задания с указанием состояния DONE. Если же для обработки запроса требуется время, то это указывается внутри возвращаемого клиенту представления ресурса-задания с помощью указания соответствующего состояния задания (WAITING или RUNNING). В этом случае клиент использует переданный URI ресурса-задания для дальнейшего опроса состояния задания и получения результата.

Подобная схема, с одной стороны, обеспечивает максимальную свободу сервиса в выборе стратегии обработки каждого отдельного запроса. С другой стороны, при реализации клиента требуется учесть оба сценария развития событий. Почему одни запросы могут быть обработаны быстро, а другие нет? Это может быть связано как с зависимостью времени выполнения алгоритма от значений входных параметров, так и просто с текущей загрузкой сервиса входящими запросами и их возможной приоритетизацией. В общем случае трудно априори предсказать режим обработки запроса и разделить запросы на синхронные и асинхронные. Исходя из этих соображений и была выбрана данная схема.

Форматы представления данных

За рамками описанной выше схемы интерфейса сервиса остался вопрос о том, какие форматы представления данных будут использовать во время взаимодействия между клиентом и сервисом. Наиболее распространенными форматами представления данных в Web являются HTML, XML и JSON. Первый формат используется, главным образом, для отображения данных пользователю через Web-браузер. Два других формата используются при реализации программных интерфейсов к Web-сервисам. Наибольшее распространение получил XML, как универсальный формат обмена данными между программными системами. В последние несколько лет набирает популярность формат JSON, который является компактной альтернативой XML и хорошо сочетается с языком JavaScript, на котором пишется большинство клиентских Web-приложений.

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

  • более компактное представление структур данных, в то время как XML ориентирован на представление произвольных документов;
  • число библиотек для работы с JSON на различных языках программирования приближается к таковому для XML;
  • удобство работы c JSON-данными на языке JavaScript.

Известным недостатком JSON является отсутствие стандартного средства описания схем, сопоставимого с языком XML Schema. Однако данный недостаток носит временный характер, так как в настоящее время ведутся активные работы над спецификацией JSON Schema.

Протокол HTTP поддерживает указание формата запроса с помощью заголовка «Content-Type», а также динамическое согласование формата ответа с помощью заголовка «Accept». Значениями указанных заголовков являются идентификаторы МIME-типов, регистрируемых организацией IANA. Данные возможности протокола HTTP позволяют поддерживать в рамках описанного интерфейса сразу несколько форматов представления данных, используемых в зависимости от типа клиента или других обстоятельств.

Получение описания сервиса

Формат запроса

Формат ответа

Если сервис с данным URI существует, то сервер возвращает описание сервиса в следующем виде:

200 OK
Content-Type: application/json

{
  "name":"SERVICE_NAME",
  "description":"SERVICE_DESCRIPTION",
  "inputs": {
    "IN_PARAM1_NAME": {"type": "..." , "title": "...", ...},
    "IN_PARAM2_NAME": {"type": "...", "title": "...", ...},
    ...
  },
  "outputs": {
    "OUT_PARAM1_NAME": {"type": "...", "title": "...", ...},
    "OUT_PARAM2_NAME": {"type": "...", "title": "...", ...},
    ...
  }
}

Поясним назначение отдельных атрибутов описания сервиса:

  • атрибут name содержит краткое имя сервиса;
  • атрибут description содержит краткое текстовое описание сервиса и/или URI документа с подробным описанием сервиса;
  • атрибут inputs содержит массив описаний входных параметров сервиса;
  • атрибут outputs содержит массив описаний выходных параметров сервиса.

Описание параметра состоит из имени параметра и его схемы, оформленной в соответствии с JSON Schema. Наиболее важными атрибутами схемы являются:

  • атрибут type, указывающий тип значения параметра;
  • атрибут title, содержащий текстовое название параметра;
  • атрибут description, содержащий текстовое описание параметра;
  • атрибут required, указывающий на то, что данный параметр является обязательным (по-умолчанию, параметры не являются обязательными);
  • атрибут default, содержащий значение параметра по умолчанию.

Приведем пример описания тестового сервиса Echo:

TODO

Коды ошибок

  • 404 Not Found - сервис с данным URI не существует
  • 500 Internal Server Error - ошибка на серверной стороне

Вызов сервиса

Формат запроса

POST SERVICE_URI
Content-Type: application/json

{
  "IN_PARAM1_NAME": IN_PARAM1_VALUE,
  "IN_PARAM2_NAME": IN_PARAM2_VALUE,
  ...
}

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

Приведем пример запроса к тестовому сервису Echo:

TODO

В приведенном выше запросе в качестве значения для параметра in5 указывается URI файла. В данном случае перед началом выполнения запроса сервис производит загрузку содержимого файла с помощью протокола HTTP. Данный подход позволяет организовать передачу данных большого объема вне тела запроса.

Формат ответа

В случае если запрос клиента принят к выполнению, то сервис возвращает следующий ответ:

202 Accepted
Location: JOB_URI
Content-Type: application/json

Текущий статус задания в формате JSON (см. п. TODO)

Статус 202 Accepted означает, что запрос принят к выполнению и его статус можно отслеживать с помощью нового ресурса-запроса, URI которого содержится в заголовке Location. В теле ответа передается текущее представление ресурса-запроса. Это позволяет клиенту сразу получить результат запроса в случае, если запрос может быть выполнен сервисом в течение короткого времени.

Приведем пример ответа на запрос к тестовому сервису Echo:

TODO

Коды ошибок

  • 404 Not Found - сервис с данным URI не существует
  • 400 Bad Request – некорректный запрос (в запросе не указаны значения всех обязательных входных параметров, значение параметра не соответствует его схеме и т.п.)
  • 500 Internal Server Error - ошибка на серверной стороне

Получение статуса и результатов задания

Формат запроса

GET JOB_URI
Accept: application/json

Формат ответа

В случае если запрос с данным URI существует и находится в состояниях WAITING или RUNNING, то сервис возвращает ответ следующего вида:

200 OK
Content-Type: application/json

{
  "state": "REQUEST_STATE",
  "info": "REQUEST_STATUS_INFO",
}

В случае если запрос находится в состоянии DONE, то добавляется атрибут result:

200 OK
Content-Type: application/json

{
  "state": "DONE",
  "info": "REQUEST_STATUS_INFO",
  "result": {
    "OUT_PARAM1_NAME": OUT_PARAM1_VALUE,
    "OUT_PARAM2_NAME": OUT_PARAM2_VALUE,
    ...
  }
}

Аналогично, если запрос находится в состоянии FAILED, то добавляется атрибут error:

200 OK
Content-Type: application/json

{
  "state":"FAILED",
  "info":"REQUEST_STATUS_INFO",
  "error":"ERROR_INFO"
}

Поясним значение каждого из используемых атрибутов:

  • обязательный атрибут state содержит текущее состояние запроса, которое может принимать одно из следующих значений: WAITING, RUNNING, DONE, FAILED;
  • необязательный атрибут info предназначен для передачи дополнительной информации о статусе выполнения запроса, отображаемой пользователю;
  • атрибут result содержит результат выполнения запроса в виде набора значений выходных параметров;
  • атрибут error содержит информацию об ошибке, приведшей к сбою при выполнении запроса.

Приведем пример ответа для тестового сервиса Echo в случае, когда выполнение запроса завершено успешно:

TODO

На приведенном выше примере видно, что файловые выходные параметры, аналогично входным параметрам, передаются при помощи указания URI файла. В данном случае клиенту передается адрес файла, соответствующего выходному параметру out6. Данный подход позволяет организовать передачу результатов большого объема.

Коды ошибок

  • 404 Not Found - задание с данным URI не существует
  • 500 Internal Server Error - ошибка на серверной стороне

Отмена задания и удаление результатов

Клиент может отменить задание с помощью метода DELETE ресурса-задания. В случае если задание уже выполнено успешно, происходит удаление всех данных, связанных с результатом задания. Таким образом, клиент дает знать сервису, что больше не нуждается в этих данных.

Формат запроса

DELETE REQUEST_URI

Формат ответа

В случае если задание с данным URI существует, то после удаления задания сервис возвращает ответ

200 OK

Коды ошибок

  • 404 Not Found - задание с данным URI не существует
  • 500 Internal Server Error - ошибка на серверной стороне

Получение файла результата запроса

После успешного выполнения запроса каждый выходной файл размещается сервисом под некоторым FILE_URI, который передается клиенту в результатах запроса. Клиент может загрузить файл с помощью метода GET ресурса-файла.

Формат запроса

GET FILE_URI

Формат ответа

В случае если файл с данным URI существует, то сервис возвращает содержимое файла в теле ответа:

200 OK
Content-Type: FILE_MIME_TYPE

FILE_DATA

Значение заголовка Content-Type соответствует типу файла и определяется, например, исходя из расширения файла.

Коды ошибок

  • 404 Not Found - файл с данным URI не существует
  • 500 Internal Server Error - ошибка на серверной стороне