Расширенное REST API

Внешняя система предназначена для подключения к системе собственного веб-сервера с наборами веб-методов и описанием типов.

Основные настройки

Чтобы приступить к настройке внешней системы, на вкладке Коннектор выберите тип Расширенное REST API. После выбора типа коннектора станут доступны поля для ввода характеристик внешней системы:

../../_images/imagee94.png
  • Порт для публикации API: укажите порт, на котором будет запущено веб-API. Должен быть уникальным в пределах одной машины.

  • Использовать https: флаг устанавливается при использовании защищенного протокола передачи данных. При активном флаге будет использован сертификат, указанный при установке.

  • Требовать авторизацию: включение авторизации пользователя, подробнее описано в настройке аутентификации.

  • Включить ограничение: управление ограничением запросов.

Ограничение количества запросов

В Платформе реализована возможность ограничения количества запросов в секунду для внешних систем Веб-сервис и Расширенное REST API.

Набор конечных точек (endpoints) у внешней системы Расширенное REST API определяется обработчиками, связанными с внешней системой. Общие настройки ограничений количества запросов в секунду производятся в настройках внешней системы. Также доступна независимая настройка ограничения для каждого связанного обработчика.

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

Перенаправление (код ответа 302 для переадресации вызова сервиса) выполняется безусловно для всех запросов без ограничений, контроль ограничения выполняется на шаге непосредственного выполнения запроса.

Установка ограничения для внешней системы

Чтобы установить ограничение для внешней системы:

  1. Перейдите на вкладку Коннектор внешней системы.

    ../../_images/image317.png
  2. Установите флаг Включить ограничение.

  3. Введите значение ограничения в поле Максимальное количество запросов в секунду.

    Максимальное количество запросов в секунду: диапазон значений 1-1000000000 (значение по умолчанию - 1000).

  4. Введите значение кода ответа в поле Код ответа при превышении лимита.

    Возможные значения кода ответа при превышении лимита: 429 (используется по умолчанию), 503.

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

Настройка аутентификации

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

Для включения аутентификации в системе установите значение true в значении ключа enabled (тип boolean), который находится в значении ключа auth (тип object).

Также в значении ключа authTypeRest (тип string), который находится в значении ключа asServer (тип object), установите тип аутентификации с возможными значениями:

  • Basic: базовый тип аутентификации.

  • Bearer: аутентификация с использованием токена на предъявителя Bearer (используется по умолчанию).

Пример части конфигурации внешней системы с настройками для включения аутентификации в системе:

{
    "$type": "DT.ClusterConfiguration.DtSystem, DT_Core",
    "config": {
        "$type": "DT.ConfigurationRepository.Configuration.Adapter.WebSystemSimpleConfig, DT_ConfigurationRepository",
        "asServer": {
            "$type": "DT.ConfigurationRepository.Configuration.Adapter.WebServerConfig, DT_ConfigurationRepository",
            "authTypeRest": "Bearer"
            "credentialsInBody": true
        },
        "auth": {
            "$type": "DT.ClusterConfiguration.AuthenticationConfig, DT_Core",
            "enabled": true,
            "usePasswordHash": false
        }
    }
}

При значении «usePasswordHash: true» для аутентификации требуется передавать не сам пароль, а только хеш от него (SHA256 в шестнадцатеричном формате).

Basic (базовый тип)

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

Bearer

При включении аутентификации с типом Bearer к API-запросам работы с внешней системой добавляется запрос получения токена Bearer (токен должен быть использован при выполнении остальных запросов работы с внешней системой) и запрос отмены токена:

  • POST запрос /api/session/token, в котором представлены параметры логина и пароля внутреннего пользователя для получения токена Bearer, который затем должен добавиться в заголовок Authorization в API-запросах работы со внешней системой; значение токена хранится в поле AccessToken json-ответа на запрос.

  • POST запрос /api/session/logout для отмены выданного токена.

    Если в настройках сервиса Управление пользователями в значении поля tokenIsUpdatable указано значение true, поле RefreshToken json-ответа на POST запрос /api/session/token хранит значение токена (поле RefreshToken) для обновления токена авторизации AccessToken (если tokenIsUpdatable = false, в RefreshToken возвращается null), при обновлении токена авторизации сохраняется сессия (SessionId). Также к API-запросам работы с внешней системой добавляется PUT запрос /api/session/token, с помощью которого можно обновить AccessToken.

Все возможности и параметры API-запросов работы со внешней системой, которые добавляются при включении аутентификации, доступны в Swagger, который запускается после создания внешней системы. Адрес Swagger доступен на странице внешней системы в ЦМ:

../../_images/sw_rest.png

Для авторизации в Swagger системы получите актуальный токен с помощью POST запроса /api/session/token, введите значение Bearer и через пробел значение полученного токена в окне Available authorizations и нажмите на кнопку Authorize.

../../_images/rest_swagger_auth.png

Передача аутентификационных данных в запросе получения токена Bearer

При аутентификации с типом Bearer выбор способа передачи аутентификационных данных в запросе получения токена Bearer (логин и пароль) осуществляется с помощью параметра credentialsInBody.

При значении credentialsInBody: true в запросе получения токена Bearer для аутентификации имя пользователя и пароль внутреннего пользователя будут переданы в теле запроса, при значении false - в параметрах запроса. Значение по умолчанию - true.

В swagger внешней системы при значении credentialsInBody: true отображается следующая информация:

../../_images/rest_swagger_auth_true.png

Пример команды curl для отправки запроса при значении параметра true:

curl --location 'http://server-address:8302/api/session/token' \
--header 'Content-Type: application/json' \
--data '{
  "login": "Логин",
  "password": "Пароль"
}'

В swagger внешней системы при значении credentialsInBody: false отображается следующая информация:

../../_images/rest_swagger_auth_false.png

Пример команды curl для отправки запроса при значении параметра false:

curl --location --request POST 'http://server-address:8302/api/session/token?login=Логин&password=Пароль'

Дополнительные настройки

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

Внимание

Перед переходом в режим редактора конфигурации сохраните внесенные данные!

Система типа REST API позволяет настроить пользовательское API с любым набором веб-методов.

В блоке config следует указать необходимый тип конфигурации адаптера.

Все актуальные примеры настроек можно взять из Swagger ЦН, контроллер XampleSystemConfig GET/examples/adapters/web Web Адаптер.

Пример конфигурации внешней системы:

{
    "$type": "DT.ClusterConfiguration.DtSystem, DT_Core",
    "config": {
        "$type": "DT.ConfigurationRepository.Configuration.Adapter.WebSystemConfig, DT_ConfigurationRepository",
        "connectorType": "Web",
        "port": 102,
        "useHttps": true,
        "replyStoreTime": 0,
        "publishSwagger": true,
        "authTypeRest": "Bearer",
        "sslProtocols": [
            "Tls",
            "Tls11",
            "Tls12"
        ],
        "auth": {
            "$type": "DT.ClusterConfiguration.AuthenticationConfig, DT_Core",
            "enabled": true,
            "usePasswordHash": false
        },
        "responseErrorSettings": {
            "$type": "DT.ConfigurationRepository.Configuration.Adapter.ResponseErrorSettings, DT_ConfigurationRepository",
            "bodyJsonTemplate": "{\n \"кодОтвета\": {errorCode},\n \"текстОшибкиРасширенный\": \"мой произвольный текст -{errorMessage}\",\n \"текстОшибкиКраткий\": \"{errorMessage}\",\n \"поляПлохие\": \"{notValidFields}\"\n}",
            "validationErrorCode": 489
        },
        "handlersList": [],
        "sendingStrategy": ""
    },
    "isActive": true,
    "folderId": null,
    "entityId": "1ee43391-769d-417b-a9d6-d9476632ea0d",
    "clusterId": "2f070fd4-ccba-4c25-bfd9-334c4a5f64a6",
    "name": "REST",
    "description": "Test",
    "version": 1,
    "tagsCollection": [],
    "className": "System",
    "classNameStr": "Внешняя система"
}

В режиме конфигурации настраиваются следующие параметры:

  • replyStoreTime (integer): время хранения сообщений, на которые не был получен ответ до истечения таймаута. Если обработчик ожидает ответа и в течение указанного таймаута ответ не приходит, то в ответе возвращается идентификатор сообщения. Если идентификатор сообщения известен, его можно передать в метод GET/{messageId} адаптера (контроллер CheckRequestState), который вернет или полученный ответ, или код ошибки.

    Примечание

    Изменение этого параметра не приводит к перезагрузке расширенного REST API и не влечет за собой перенагрузку системы.

  • auth (object): настройки аутентификации для обработчиков с установленным флагом Требуется авторизация.

  • publishSwagger (boolean): настройка публикации Swagger. При значении false он не публикуется, но при этом методы работают как и раньше. Swagger для данной конфигурации откроется по адресу (При значении true): https://localhost:6633/swagger/index.html

  • sslProtocols (array of strings): параметр настройки протоколов SSL. Поддерживается работа со следующими протоколами: TLS1.0, TLS1.1, TLS1.2. Доступны к использованию только протоколы, указанные в параметрах TLS при запросах к системе. Настройка протокола учитывается только при значении true параметра useHttps (настройка Использовать https). Актуальные настройки SSL отображаются в ЦМ:

    ../../_images/ssl_cm.png

    Примечание

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

  • responseErrorSettings (object): включение дополнительной валидации API-запросов, отправленных к Расширенному REST API, для привязанных веб-обработчиков с возможностью формировать тело ответа в формате JSON. По умолчанию отсутствует в конфигурации внешней системы и может быть добавлен вручную.

  • bodyJsonTemplate (string): (экранированная JSON-строка-шаблон тела ошибки) - формат текста ответа на запрос, который не прошел валидацию. В шаблоне доступны плейсхолдеры (переменные) вроде {errorCode}, {errorMessage}, {notValidFields}. Можно задавать один или все параметры.

  • validationErrorCode (integer): HTTP-код, который вернется при ошибке валидации. По умолчанию 0, значение не требует изменений, если внешняя система не предъявляет особых требований к HTTP-коду ошибки.

    Возможна настройка validationErrorCode и/или bodyJsonTemplate.

Запрос считается невалидным, и возвращается ответ по responseErrorSettings, если выполняется хотя бы одно из условий:

  1. Внутренние исключения валидатора. Если обработчик выбрасывает валидационное исключение (ValidateParametersException), запрос считается невалидным: возвращается HTTP-код из исключения (или responseErrorSettings.validationErrorCode), а тело ошибки формируется по responseErrorSettings.bodyJsonTemplate с подстановкой деталей (код, сообщение, список полей).

  2. В ответе обработчика приходит заполненные свойства ResponseCode из диапазона ошибок 400–500.

  3. Нарушены обязательные параметры (не передан или тип не соответствует ожиданию - например, ожидается integer, а пришел boolean).

  4. Возник WebServiceException (внутреннее системное исключение).

Примечание

Если responseErrorSettings настроен, то при ошибке авторизации и ошибке отправки на сервер ответ также возвращается в едином JSON-формате ошибки (на код ответа в подобных случаях валидация не влияет). Все ошибочные ответы формируются одинаково, без исключений для этих случаев.

При настроенном responseErrorSettings, если у веб-обработчика установлен чек-бокс Ожидание ответа и во внешнюю систему, к которой привязан этот обработчик, отправляется сообщение Это ответ, у которого добавлены свойства сообщения ResponseCode и ResponseMessage, срабатывают настройки валидации responseErrorSettings.

Подробно о конструкциях описано в валидации API.

После создания системы можно добавить обработчики типа Веб-обработчик. Это можно сделать из редактора обработчика (вкладка Системы) или из редактора системы (раздел handlersList).

После внесения данных нажмите на кнопку Сохранить изменения, после этого нажмите на кнопку Применить конфигурацию.

Свойства сообщения, зависимые от настроек обработчика

  • IsArray - принимает значение true, если выставлен флаг массив у запроса.

  • DataType - содержит идентификатор пользовательского типа, если запрос является объектом этого типа.

  • SystemDataType - содержит идентификатор типа метаданных, если запрос является объектом этого типа.

  • Body - содержит массив байт запроса, доступно только через методы.

  • Свойства сообщения:
    • AnswerRequired - принимает значение true, если установлен флаг Ожидание ответа или заполнена переменная на вкладке Ответ. Получение значения осуществляется через метод GetBoolOrNullProperty(«AnswerRequired»).

    • AnswerDataType - содержит идентификатор типа данных, если ответ является объектом этого типа. Получение значения осуществляется через метод GetStringOrNullProperty(«AnswerRequired»).

    • AnswerSystemDataType - содержит идентификатор типа метаданных, если ответ является объектом этого типа. Получение значения осуществляется через метод GetStringOrNullProperty(«AnswerSystemDataType»).

    • MethodType - содержит тип метода (Get/Post/Put/Delete). Получение значения осуществляется через метод GetStringOrNullPropert(«MethodType»).

    • MethodId - идентификатор вызванного обработчика. Можно получить с помощью метода коллекции свойства GetGuidProperty(«MethodId»).

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

Внимание

С версии 3.1.2 изменен механизм выбора обработчиков сообщений. Теперь обработчик определяется по типу данных (SystemDataType или DataType). Если в конфигурации внешней системы настроено несколько обработчиков одного типа, необходимо указывать тип данных явно («systemDataType»: «имя\id внешнего типа»). При отсутствии типа система не сможет определить нужный обработчик, и сообщение не будет обработано после обновления версии на 3.1.2 и выше.

Работа с массивами

Если на вкладке Ответ установлена переменная-массив, а в ответном сообщении пришел не массив, то:

  • пустое тело интерпретируется как пустой массив;

  • непустое тело интерпретируется как массив из 1го элемента.

Если на вкладке Ответ установлена переменная-не массив, а пришел массив, то:

  • пустой массив интерпретируется как пустое тело ответа;

  • массив из 1 элемента интерпретируется как тело ответа;

  • массив из более 1 элемента интерпретируется как ошибка.

Коды ответных сообщений для веб-системы

Задать код ошибки для отправки сообщения об ошибке обработки в веб-адаптер:

ВхСообщ.SetProperty(«ResponseCode», «405»); ВхСообщ.SetProperty(«ResponseMessage», «Ошибка 405»);

Для сообщений, формируемых через Расширенный REST API, обрабатываются только коды от 400 до 499. Если в свойстве ResponseCode код вне указанного диапазона, фактический ответ будет возвращен с кодом 200 с записью в лог:

2020-08-17 10:29:26,537 [30] WARNING WebServiceExecutor - В ответе на сообщение для метода 0b00fd8e-c279-48af-9467-452784458540 ,corrId = 9ee2831e-b295-4e81-bf92-bf5d580894bd получен неверный код результата обработки 500

Код

Название

Описание

0

Внутренний код платформы. Обработчик сообщения не найден. Действие не произведено (устанавливается по умолчанию).

114

Внутренний код платформы. Ошибка создания сообщения в 1С.

200

ОК

Запрос выполнен успешно, и запрошенная информация содержится в ответе.

202

Accepted

Запрос получен, но еще не обработан.

400

Bad Request

Запрос не может быть понят сервером. Отправляется, когда никакая другая ошибка не применима, или если точная ошибка неизвестна или не имеет собственного кода ошибки.

401

Unauthorized

Запрошенный ресурс требует аутентификации.

402

Payment Required

Требуется оплата. Предполагается использовать в будущем.

403

Forbidden

Сервер отказывается выполнить запрос.

404

Not Found

Запрошенный ресурс не существует на сервере.

405

Method Not Allowed

Метод запроса (POST или GET) не разрешен на запрашиваемом ресурсе.

406

Not Acceptable

Клиент указал заголовками Accept, что он не будет принимать ни одно из доступных представлений ресурса.

407

Proxy Authentication Required

Запрошенный прокси-сервер требует аутентификации.

408

Request Timeout

Клиент не отправил запрос в течение ожидаемого сервером времени.

409

Conflict

Запрос не может быть выполнен из-за конфликтного обращения к ресурсу.

410

Gone

Запрошенный ресурс больше не доступен.

411

Length Require

Отсутствует заголовок требуемой длины.

412

Precondition Failed

Условие, установленное для этого запроса, не выполнено, и запрос не может быть выполнен.

413

Payload Too Large

Запрос является слишком большим для того, чтобы сервер его обработал.

414

URI Too Long

URI слишком длинный.

415

Unsupported Media Type

Запрос является неподдерживаемым типом.

416

Range Not Satisfiable

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

417

Expectation Failed

По каким-то причинам сервер не может удовлетворить значению поля Expect заголовка запроса.

418

I’m a teapot

Ответ для запросов, которые не могут быть обработаны сервером.

419

Authentication Timeout

Используется в качестве альтернативы коду 401, которые прошли проверку подлинности, но лишены доступа к определенным ресурсам сервера.

421

Misdirected Request

Запрос был перенаправлен на сервер, не способный дать ответ.

422

Unprocessable Entity

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

423

Locked

Целевой ресурс из запроса заблокирован от применения к нему указанного метода.

424

Failed Dependency

Реализация текущего запроса может зависеть от успешности выполнения другой операции. Если она не выполнена и из-за этого нельзя выполнить текущий запрос, то сервер вернет этот код.

426

Upgrade Required

Клиент должен переключиться на другой протокол.

428

Precondition Required

Сервер указывает клиенту на необходимость использования в запросе заголовков условий.

429

Too Many Requests

Клиент попытался отправить слишком много запросов за короткое время.

431

Request Header Fields Too Large

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

449

Внутренний код платформы. Некорректный формат сообщения. Требуется разблокировка сообщения в очереди.

450

Внутренний код платформы. Отмена обработки сообщения в 1С.

451

Unavailable For Legal Reasons

Доступ к ресурсу закрыт по юридическим причинам.

452

Внутренний код платформы. Отсутствует доступ к хранилищу данных.

500

Ошибка обработки сообщения на стороне сервера.

503

Service unavailable

Сервер не готов обработать данный запрос.

550

Превышен лимит использования диска.

551

Ошибка передачи сообщения.

552

Сообщение отклонено.

553

Отсутствуют получатели сообщения.

555

Зацикливание пути доставки сообщения.

556

Время жизни сообщения истекло.

557

Ошибка трансформации.

558

Ошибка обработки сообщения.

562

Истечение таймаута передачи данных.

563

Внешний сервис недоступен.

565

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

600

Отмена обработки сообщения из-за отсутствия подключения.

700

Доступ запрещен.

701

Срок действия токена истек.

702

Пользователь не найден.

800

Отложить сообщение.

801

Превышено максимальное количество откладывания сообщения.

900

Доставка сообщения осуществлена части получателей.

1000+

Внутренний код платформы. Ошибка плагина.

Примечание

В таблице приведены как стандартные HTTP-коды ответов, так и внутренние коды обработки Платформы, которые могут использоваться в свойствах сообщений и журнале.

Если код отсутствует в таблице, то возвращается ошибка без описания.

Описание веб-обработчиков находится в разделе Веб-обработчики

Мониторинг

В Журнале ЦМ отображается информация о запросах, выполненных с ошибкой:

../../_images/monitoring_log1.png

В Событиях есть возможность сохранять (логировать) заголовки из сообщений. Заголовки отображаются в поле Детали:

../../_images/monitoring_log2.png

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

../../_images/url1.png

При передаче сообщения в Платформу значения заголовков устанавливаются в свойствах сообщения ("properties"):

"customFields": {
    "$type": "DT.ExternalMessageData, DT_TypeBuilder.Entities",
    "id": "e34042c5-2ef4-4d1d-a6a9-ab8e2c289502",
    "properties": {
        "$type": "SystemModels.PropertiesCollection, DT_TypeBuilder.Entities",
        "properties": {
            "$type": "System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib],[DT.Property, DT_TypeBuilder.Entities]], System.Private.CoreLib",