OpenAPI коннектор#

Данный конектор позволяет читать и писать данные через HTTP/REST API, используя спецификацию OpenAPI. Коннектор принимает на вход схему OpenAPI и представляет endpoints в виде таблиц, которые можно читать, писать и передавать значения в методы через WHERE.

Конфигурация коннектора#

connector.name=openapi
spec-location=http://api.example/api/spec.yaml
base-uri=http://api.example/api/v1
authentication.type=BASIC
authentication.basic.username=${ENV:OPENAPI_USERNAME}
authentication.basic.password=${ENV:OPENAPI_PASSWORD}

Параметры конфигурации#

Свойство конфигурации

Переменная окружения

Описание

spec-location

OPENAPI_SPEC_LOCATION

URL или имя файла, содержащее спецификацию OpenAPI (JSON или YAML)

base-uri

OPENAPI_BASE_URI

Базовый URL для API, обычно содержит версию API

authentication.type

OPENAPI_AUTH_TYPE

Тип аутентификации. Один из: AUTO, NONE, BASIC, BEARER, API_KEY, OAUTH_CLIENT_CREDENTIALS. При AUTO тип определяется из спецификации, а подходящие учётные данные выбираются автоматически.

authentication.basic.username

OPENAPI_BASIC_USERNAME

Имя пользователя для BASIC аутентификации

authentication.basic.password

OPENAPI_BASIC_PASSWORD

Пароль для BASIC аутентификации

authentication.bearer.token

OPENAPI_BEARER_TOKEN

Bearer-токен для BEARER аутентификации

authentication.api-key.name

OPENAPI_API_KEY_NAME

Имя заголовка / query-параметра / cookie для API_KEY аутентификации (при AUTO берётся из спецификации)

authentication.api-key.value

OPENAPI_API_KEY_VALUE

Значение API-ключа для API_KEY аутентификации

authentication.oauth.client-id

OPENAPI_OAUTH_CLIENT_ID

OAuth Client ID для OAUTH_CLIENT_CREDENTIALS аутентификации

authentication.oauth.client-secret

OPENAPI_OAUTH_CLIENT_SECRET

OAuth Client Secret для OAUTH_CLIENT_CREDENTIALS аутентификации

authentication.oauth.token-url

OPENAPI_OAUTH_TOKEN_URL

URL токен-эндпоинта для OAUTH_CLIENT_CREDENTIALS аутентификации (при AUTO берётся из спецификации)

max-requests-per-second

OPENAPI_MAX_REQUESTS_PER_SECOND

Максимальное число HTTP-запросов в секунду, исполняемых для одного узла CedrusData

max-splits-per-second

OPENAPI_MAX_SPLITS_PER_SECOND

Максимальное число splits в секунду, генерируемое при исполнении запроса

domain-expansion-limit

OPENAPI_DOMAIN_EXPANSION_LIMIT

Максимальное число discrete domain values, генерируемое из range-предикатов (коррелируется с числом выполненных HTTP-запросов)

Режим AUTO#

При authentication.type=AUTO коннектор читает требования к аутентификации из спецификации OpenAPI и выбирает первый подходящий тип, для которого сконфигурированы учётные данные. Если ни один тип не подходит — запрос завершается ошибкой.

В режиме AUTO не следует указывать authentication.api-key.name и authentication.oauth.token-url — эти значения берутся из спецификации.

Дополнительные параметры конфигурации HTTP клиента#

Свойство конфигурации

Пример значения

Описание

openapi.http-client.log.enabled

true

Включение журналирования вызовов

openapi.http-client.log.path

logs

Каталог журналов

openapi.http-client.trust-store-path

certs/truststore.jks

Путь к файлу хранилища доверенных сертификатов на сервере

openapi.http-client.trust-store-password

changeit

Пароль от файла хранилища доверенных сертификатов

Другие аналогичные параметры можно найти тут: Конфигурация HTTP-клиента (добавляется префикс openapi.)

Быстрый старт#

В данном примере будем использовать docker-образ Microcks для создания mock-сервиса по спецификации OpenAPI.

  1. Запустите docker-образ Microcks:

docker run -d --name microcks -p 8585:8080 quay.io/microcks/microcks-uber:latest-native
  1. В примере ниже мы сделаем mock-сервис с двумя endpoints: первый для суммирования чисел и второй для получения данных в виде списка. Сохраните данную спецификацию в файл service.yaml.

openapi: 3.0.3
info:
  title: ExampleAPI
  version: 1.0.0
  description: CedrusData OpenAPI sample service

paths:
  /sum:
    post:
      operationId: sumNumbers
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [a, b]
              properties:
                a:
                  type: integer
                  format: int64
                b:
                  type: integer
                  format: int64
            examples:
              sum_ok:
                value:
                  a: 2
                  b: 3
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required: [sum]
                properties:
                  sum:
                    type: integer
                    format: int64
              examples:
                sum_ok:
                  value:
                    sum: 5

  /my/pets:
    get:
      responses:
        "200":
          description: A list of pets
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Pet'
              examples:
                my_pets:
                  value:
                    - id: 1
                      name: Zaza
                    - id: 2
                      name: Tigress
                    - id: 3
                      name: Maki
                    - id: 4
                      name: Toufik

components:
  schemas:
    Pet:
      allOf:
        - $ref: '#/components/schemas/NewPet'
        - type: object
          properties:
            id:
              format: int64
              type: integer
          required:
            - id
    NewPet:
      type: object
      properties:
        name:
          type: string
      required:
        - name
  1. Продеплойте сервис в Microcks:

curl -fsS "http://localhost:8585/api/artifact/upload?mainArtifact=true" -F "file=@./service.yaml"
  1. Перейдите в UI сервера Microcks http://localhost:8585

  2. В левой части перейдите на вкладку APIs | Services и убедитесь что сервис ExampleAPI доступен.

  3. Проверьте работоспособность сервиса из командной строки:

curl -X POST "http://localhost:8585/rest/ExampleAPI/1.0.0/sum" -H "Content-Type: application/json" -d '{"a":2, "b":3}'
curl -X GET "http://localhost:8585/rest/ExampleAPI/1.0.0/my/pets"

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

  1. Настройте коннектор OpenAPI в CedrusData Engine (etc/catalog/openapi.properties). В случае, если вы запускаете CedrusData Engine в Docker/K8s, замените localhost на адрес хоста, где запущен Microcks.

connector.name=openapi
spec-location=http://localhost:8585/api/resources/ExampleAPI-1.0.0.yaml
base-uri=http://localhost:8585/rest/ExampleAPI/1.0.0
authentication.type=NONE
  1. Перезапустите CedrusData Engine, подключитесь к SQL консоли и проверьте работу коннектора:

select * from openapi."default".my_pets;
select * from openapi."default".sum where a=3 and b=2;
  1. Остановите запущенный ранее docker-образ:

docker stop microcks
docker rm microcks

Маппинг схем#

Для сопоставления схемы OpenAPI с таблицами и столбцами SQL используются следующие правила:

  • Пути сопоставляются с таблицами; имена таблиц являются путями, где camelCase преобразовываются в snake_case а специальные символы (например /, ) преобразуются в подчеркивания.

  • Операции SQL сопоставляются с методами HTTP:

    • Оператор SELECT использует метод GET (или POST, если GET-запрос недоступен);

    • Оператор INSERT использует POST или PUT;

    • Оператор UPDATE использует PATCH или POST;

    • Оператор DELETE использует DELETE.

  • Все параметры запроса сопоставляются со столбцами, включая путь, запрос и параметры заголовка.

  • Поля ответа HTTP OK (200) сопоставляются со столбцами.

  • Если для запроса SELECT используется POST-запрос, поля тела запроса также сопоставляются со столбцами.

  • Все столбцы однозначно идентифицируются — если в ответе и параметрах встречается поле с одинаковым именем, но разным типом данных, оно будет сопоставлено с несколькими столбцами с числовыми суффиксами (_2, _3, и т.д.). Поля тела запроса имеют _req суффикс.

Расширения OpenAPI#

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

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

Постраничный просмотр результатов#

OpenAPI может применять постраничный просмотр, который вы можете определить в разделе x-trino.pageParam:

paths:
  /records:
    get:
      responses:
        # ...
      x-trino:
       pageParam: "page"
       limitParam: "per-page"
       resultsPath: "$response.body#/workflows"
       totalResultsPath: "$response.body#/total_count"

Коннектор в настоящей реализации поддерживает только тип page.

Обработка ошибок#

Если коннектор выполняет вызов API, а сервер возвращает ошибку, то ошибка будет возвращена пользователю CedrusData Engine. Ошибка содержит только код статуса HTTP, а тело ответа пользователю недоступно. Это сделано из соображений безопасности - текст ответа может содержать конфиденциальную информацию.

Чтобы извлечь сообщение об ошибке из ответов об ошибках, установите значение x-trino.errorPath как указано в примере ниже:

paths:
  /records:
    get:
      responses:
        # ...
      x-trino:
       errorPath: "$response.body#/message"

Рекомендации по использованию и ограничения#

  • Коннектор рекомендуется использовать преимущественно для операций чтения. Операции INSERT, DELETE, UPDATE могут иметь ограничения.

  • Коннектор не пробрасывает фильтрующие предикаты на источник данных, как следствие работа с большими объёмами данных может вызвать проблемы производительности и повышенное потребление памяти.