Компонент «XML API»

Компонент обеспечивает программный интерфейс доступа к отчетам, формам и реестрам системы. Работа с данными идет на уровне матриц (таблиц) чисел, а не на уровне структуры данных или показателей.

Сервис экспорта данных позволяет получить данные из табличного представления (отчета, формы или реестра) в виде таблицы чисел. Для экспорта необходимо знать идентификатор отчета/формы/реестра, смысл его параметров (если они есть), и смысл данных в самом отчете/форме/реестре. Сервис экспорта не предоставляет информации о структуре табличного представления - т.е. о том, какие показатели и фильтры используются в его строках и столбцах.

Сервис импорта данных позволяет записать (удалить, обновить) данные в заданной форме или реестре. Аналогично экспорту, работа идет на уровне таблицы чисел, и нужно знать смысл формы/реестра, в который импортируются данные.

Технические особенности решения

NetDB выступает в роли сервера, а внешняя информационная система (далее - ИС) - в роли клиента.

Компонент «XML API» обеспечивает программный интерфейс доступа к данным NetDB по протоколу HTTP. Передаваемые данные представляются в формате XML.

Чтобы получить данные NetDB, внешняя система обращается к серверу NetDB с запросом GET.

Чтобы передать данные в NetDB, внешняя система обращается к серверу NetDB с запросом POST.

Ограничение доступа внешней ИС к данным обеспечивается стандартными средствами платформы NetDB.

Обмен запросами можно осуществлять разными способами - например, с помощью кроссплатформенной утилиты командной строки curl.

Подготовка к взаимодействию с внешней ИС

1. Регистрация внешней ИС как пользователя NetDB

Нужно зарегистрировать внешнюю ИС как пользователя NetDB, для чего обратиться к администратору системы. Пользователю должны быть назначены роли, обеспечивающие доступ к данным системы NetDB. Права доступа, назначенные этому пользователю, определяют возможности внешней ИС при экспорте и импорте данных. Подробнее о правах доступа к данным см. раздел Компонент «Роли пользователей».

Рекомендуется следующий сценарий настройки прав доступа к данным:

  • В справочник «Группы показателей» добавить новые группы показателей, в которые в дальнейшем будут включены экспортируемые и импортируемые показатели:
_images/sample_desc_group.png
  • В справочник «Группы отчетов» добавить новую группу отчетов, в которую будут включены отчеты, экспортируемые во внешнюю ИС:
_images/sample_report_group.png
  • В справочник «Группы реестров» добавить новые группы реестров, в которые будут включены реестры, экспортируемые во внешнюю ИС и импортируемые из внешней ИС:
_images/sample_registry_group.png
  • В справочник «Группы форм» добавить новую группу форм, в которую будут включены формы, импортируемые из внешней ИС:
_images/sample_form_group.png
  • Создать новую роль и предоставить ей доступ на просмотр отчетов из созданной группы отчетов, доступ на просмотр и ввод данных в реестры из созданных групп реестров, доступ на ввод данных в формы из созданной группы форм, доступ на просмотр показателей и запись в показатели из созданных групп показателей, а также доступ на просмотр показателей из группы (*)Системные показатели).
_images/sample_role1.png _images/sample_role2.png
  • Создать учетную запись пользователя, представляющего внешнюю ИС в системе NetDB, присвоить этому пользователю созданную роль:
_images/sample_is.png
  • В нижней части страницы редактирования профиля пользователя нажать кнопку «Новый ключ» для генерации ключа авторизации.
_images/sample_key.png

Сгенерированный ключ отображается в профиле пользователя:

_images/sample_key_2.png

Этот ключ в дальнейшем будет использоваться для авторизации запросов внешней ИС.

2. Подготовка данных для экспорта (импорта)

Нужно построить (или выбрать из уже существующих) табличное представление (отчет, форму или реестр), содержащее данные для экспорта (импорта).

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

_images/sample_report.png

Построенный (или выбранный) отчет (форму, реестр) нужно включить в соответствующую группу отчетов (группу форм, группу реестров), доступную пользователю, представляющему внешнюю ИС.

_images/sample_group.png

Показатели, используемые в отчете, нужно включить в соответствующую группу показателей, доступную пользователю.

_images/sample_desc_in_group.png

3. Проверка доступности данных

Проверить, что данное табличное представление (отчет, форма или реестр) доступно для чтения или записи пользователю, от имени которого будет работать внешняя ИС.

_images/sample_data.png

4. Экспорт (импорт) данных во внешнюю ИС

Для получения данных NetDB нужно использовать сервис экспорта данных.

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

Авторизация

Для авторизации запросов к серверу NetDB используется ключ авторизации, сгенерированный для пользователя, представляющего внешнюю ИС.

Авторизация для сервисов экспорта и импорта происходит одинаково: при совершении запроса нужно выставить в HTTP-заголовке ключ авторизации Netdb-Api-Key.

Пример запроса на экспорт данных с ключом авторизации:

curl -X GET http://127.0.0.1:8000/api/1/359262 -H "Netdb-Api-Key:XaPpwNWzNE"

При ошибке авторизации возвращается ответ со статусом 200, в xml:

<?xml version="1.0" encoding="UTF-8"?>
<error kind="auth">
</error>

Сервис экспорта данных

Для экспорта данных используется метод GET.

Запрос на экспорт данных

URL формируется следующим образом:

http://<host>/api/<v>/<id>/?<params>

где

  • вместо <host> подставляется имя сервера NetDB,
  • вместо <v> подставляется версия XML API,
  • вместо <id> подставляется идентификатор отчета, который нужно экспортировать (в интерфейсе системы идентификатор отчета - это набор цифр после последнего символа «/» в url страницы просмотра данного отчета),
  • вместо <params> подставляется строка параметров отчета.

Строка параметров содержит список параметров отчета с разделителем «?». Для каждого параметра указывается идентификатор показателя, соответствующего данному параметру. В строке параметров отчета параметры следуют в том же порядке, что и параметры в интерфейсе NetDB при просмотре данного отчета.

Пример строки параметров для отчета с двумя параметрами:

param=123&param=789989

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

param=123&param=789989&headers=true

Пример запроса к серверу по адресу http://system.sample.com для экспорта отчета с id=34678 и с двумя параметрами:

curl -X GET http://system.sample.com/api/1/34678/?param=123&param=789989 HTTP/1.1 -H "Netdb-Api-Key:fasdf6sa7df8sdf67d8df687f6dfdaa"

Ответ на запрос в случае успешного экспорта

Ответ на запрос приходит в формате xml. При успешном экспорте ответ содержит элемент верхнего уровня data, элемент params (если у отчета есть параметры - в них перечислены параметры, которые были в get-запросе), и элемент table, устроенный как таблица в HTML. В tr лежат строки, а сами значения содержатся в элементах td:

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <params>
    <param>123</param>
    <param>789989</param>
  </params>
  <table>
    <tr>
      <td></td>
      <td>55</td>
      <td>59</td>
    </tr>
    <tr>
      <td>88</td>
      <td>99</td>
      <td>890</td>
    </tr>
    <tr>
      <td>44</td>
      <td>55</td>
      <td></td>
    </tr>
  </table>
</data>

Если для построения запрошен отчет с заголовками (в get-параметрах есть headers), то заголовки будут обозначены элементами th, у которых могут быть атрибуты rowspan и colspan - их смысл аналогичен атрибутам тега th в HTML. Пример:

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <params>
    <param>123</param>
    <param>789989</param>
  </params>
  <table>
    <tr>
      <th colspan="2">Общий заголовок</th>
    </tr>
    <tr>
      <th>Первый столбец</th>
      <th>Второй столбец</th>
    </tr>
    <tr>
      <th rowspan="2">Первые две строки</th>
      <th>Первая строка</th>
      <td></td>
      <td>55</td>
      <td>59</td>
    </tr>
    <tr>
      <th>Вторая строка</th>
      <td>88</td>
      <td>99</td>
      <td>890</td>
    </tr>
    <tr>
      <th colspan="2">Третья строка</th>
      <td>44</td>
      <td>55</td>
      <td></td>
    </tr>
  </table>
</data>

Ограничение доступа к данным

Если в клетке отчета есть значение, но у пользователя NetDB, от имени которого производится операция, нет прав на его просмотр, то в клетке экспортированной таблицы будет пусто.

Ответ на запрос в случае ошибки при задании параметров

При неправильном количестве параметров возвращается сообщение об ошибке, например:

<?xml version="1.0" encoding="UTF-8"?>
<error kind="params">
  Ожидалось параметров: 3, получено параметров: 0
</error>

При ошибке в формате значений параметров возвращается ответ, который содержит исходные значения параметров и пояснение об ошибке, например:

<?xml version="1.0" encoding="UTF-8"?>
<error kind="value_format">
  <params>
    <param>97896</param>
    <param error="Введите дату в формате, принятом в системе">2011</param>
  </params>
</error>

Сервис импорта данных

Для импорта данных используется метод POST.

Запрос на импорт данных

URL формируется следующим образом:

http://<host>/api/<v>/<id>

где

  • вместо <host> подставляется имя сервера NetDB,
  • вместо <v> подставляется версия XML API,
  • вместо <id> подставляется идентификатор формы/реестра, который нужно экспортировать (в интерфейсе системы идентификатор формы/реестра - это набор цифр после последнего символа «/» в url страницы просмотра данной формы/реестра).

Импортируемые данные передаются в xml-формате, аналогичном формату экспортируемых табличных данных (см. выше).

Элемент верхнего уровня - data. Если у отчета есть параметры, то первый вложенный элемент - params. Внутри него должно быть столько элементов param, сколько есть параметров у отчета. Внутри элемента param указывается значение соответствующего параметра отчета.

Если параметров нет, то и элемента params быть не должно, а его наличие будет считаться ошибкой.

Далее следует обязательный элемент table, организованный как в HTML. Внутри него должно быть столько элементов tr, сколько есть строк в отчете. Внутри каждого tr должно быть столько td, сколько в отчете столбцов. Внутри каждого td указываются значение в данной клетке отчета. Если значение пустое (пустая строка), а в системе в этой клетке есть значение, то подразумевается удаление этого значения.

Передаваемые данные кодируются в формате application/x-www-form-urlencoded.

Пример запроса к серверу по адресу http://system.sample.com для импорта данных в форму с id=7715257 с одной строкой и двумя столбцами:

curl -X POST -H 'Netdb-Api-Key: HbzTyZVLYz' -i --data 'data=<data><table><tr><td>20</td><td>35</td></tr></table></data>' 'http://system.sample.com/api/1/7715257/'

Пример данных в формате xml для формы с двумя параметрами, тремя строчками и двумя столбцами:

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <params>
    <param>97896</param>
    <param>2011 г.</param>
  </params>
  <table>
    <tr>
      <td></td>
      <td>59</td>
    </tr>
    <tr>
      <td>99</td>
      <td>890</td>
    </tr>
    <tr>
      <td>44</td>
      <td></td>
    </tr>
  </table>
</data>

Ответ на запрос в случае успешного импорта

Ответ от сервера приходит со статусом 200 независимо от ошибок в запросе клиента.

При успешном импорте данных возвращается ответ следующего вида (в атрибутах updated, created и deleted указано соответственно число обновленных, созданных и удаленных объектов):

<?xml version="1.0" encoding="UTF-8"?>
<data updated="4" created="1" deleted="1">
</data>

Ответ на запрос в случае ошибки в формате xml

При ошибке в формате xml возвращается сообщение об ошибке («Невалидный XML», или «Не найден элемент data» и т.п.):

<?xml version="1.0" encoding="UTF-8"?>
<error kind="invalid_request">
  Невалидный xml
</error>

Ответ на запрос в случае ошибки в формате значений

При ошибке в формате значений (не важно, параметров или данных в клетках таблицы) возвращается исходный запрос в элементе error, где к ошибочным полям (элементы params или td) добавлен атрибут error, поясняющий смысл ошибки. Текст ошибки аналогичен тексту ошибок в web-интерфейсе системы.

Ответ на запрос в случае ошибки в правах доступа

При ошибке в правах доступа к полям (к элементу td) добавляется атрибут permission_error, содержащий сообщение об ошибке:

<?xml version="1.0" encoding="UTF-8"?>
<error kind="value_format">
  <params>
    <param>97896</param>
    <param error="Введите дату в формате...">2011</param>
  </params>
  <table>
    <tr>
      <td></td>
      <td error="Введите целое число">78.3</td>
      <td>59</td>
    </tr>
    <tr>
      <td permission_error="У вас нет прав на запись в показатель...">88</td>
      <td>99</td>
      <td>890</td>
    </tr>
    <tr>
      <td>44</td>
      <td>55</td>
      <td></td>
    </tr>
  </table>
</error>

При наличии хотя бы одной ошибки сохранение данных не происходит.

Импорт в реестры

Реестры отличаются от отчетов и форм тем, что у них не задано количество строк. Поэтому для поддержки как обновления, так и добавления данных в реестр вводятся новые элементы: keys и key.

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

Для описания ключей к элементу data нужно добавить элемент keys. Внутри него должен находиться один или более элемент key, значение которого - индекс столбца реестра (индекс начинается с нуля, т.е. первый столбец имеет индекс 0, второй столбец - индекс 1 и т.п.).

Пример запроса на импорт с ключами (ключ записи - комбинация первого и второго столбцов):

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <params>
    <param>97896</param>
  </params>
  <keys>
    <key>0</key>
    <key>1</key>
  </keys>
  <table>
    <tr>
      <td>218</td>
      <td>55.238</td>
      <td>2010 г.</td>
    </tr>
    <tr>
      <td>218</td>
      <td>57.813</td>
      <td>2011 г.</td>
    </tr>
  </table>
</data>

При недопустимом индексе ключевого столбца (в случае, когда данный реестр не имеет столбца с указанным индексом) возвращается сообщение об ошибке, где к соответствующему элементу key добавляется атрибут error:

<?xml version="1.0" encoding="UTF-8"?>
<error>
  <params>
    <param>97896</param>
  </params>
  <keys>
    <key>0</key>
    <key error="Недопустимый индекс столбца">3</key>
  </keys>
  <table>
    <tr>
      <td>218</td>
      <td>55.238</td>
      <td>2010 г.</td>
    </tr>
    <tr>
      <td>218</td>
      <td>57.813</td>
      <td>2011 г.</td>
    </tr>
  </table>
</error>

Если данный набор столбцов ключом не является, т.е. если в реестре уже существуют два объекта с такими ключами, то выдается сообщение об ошибке. В остальном импорт в реестр происходит так же, как импорт в отчет или форму.

Форматы значений данных и параметров

Форматы и примеры для всех типов значений, которые используются в данных (в элементах td) или в значениях параметров (в элементах param):

  • Число - десятичное число с плавающей точкой, разделителем является точка или запятая. Пример: «3.12159265». Возможно также представление в экспоненциальном виде: «6.022e23»;
  • Целое - десятичное число, может быть отрицательным. Пример: «60», «-127».
  • Объект - идентификатор объекта или целое число (может быть отрицательным). Идентификатор объекта можно узнать на странице объекта в соответствующем справочнике.
  • Период - некоторый промежуток времени.

Форматы типов периодов:

  • Год: 2012 г.
  • 3 квартала: 1 кв. 2012 г. - 3 кв. 2012 г.
  • Полугодие: 1 п. 2012 г.
  • Квартал: 1 кв. 2012 г.
  • Месяц: январь 2012 г.
  • Декада: 2 декада января 2012 г.
  • Неделя: с 17.01.2012 по 24.01.2012
  • День: 17.01.2012, 2012-01-17

Работа с кросс-доменными запросами

Возможно обращение к XML API системы из стороннего web-интерфейса. API работает с кросс-доменными запросами, поддерживает метод OPTIONS и необходимые заголовки запроса, который автоматически посылается браузером перед исполнением кросс-доменного запроса (подробнее см. https://learn.javascript.ru/xhr-crossdomain).