API управления

OpenAPI и клиенты

Где лежит спецификация, как она собирается, как сгенерировать по ней клиент и как открыть её в Postman.

На этой странице · 4

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

Где лежит

curl -s http://localhost:8080/api/v1/openapi.json -o openapi.json

Маршрут отдаётся без авторизации: за спецификацией клиент идёт до того, как у него появился ключ. Рядом лежит GET /api/v1/meta — короткая справка о версии, способах входа, лимитах и постраничности, тоже без ключа.

Формат — OpenAPI 3.1.0. В документе:

Что внутри

РазделСодержимое
info.descriptionспособы входа и действующее ограничение частоты
serversадрес, по которому клиент реально пришёл, плюс /api/v1
securitybearerAuth (серверный ключ) и cookieAuth (сессия кабинета)
pathsвсе маршруты; у каждой операции свой operationId
components.schemas.Errorобщий конверт ошибки
x-scopesполный список областей доступа с описаниями

В описании каждой операции есть строка «Требуемая область доступа», а в её responses перечислены коды отказа — 400, 401, 403, 404, 429 и, где это осмысленно, 409 и 422.

Адрес в servers — тот, по которому пришёл запрос

За обратным прокси в спецификацию попадает публичный адрес, а не localhost: иначе сгенерированный по ней клиент ходил бы в никуда.

Генерация клиента

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

curl -s http://localhost:8080/api/v1/openapi.json -o openapi.json
npx openapi-typescript openapi.json -o api.d.ts

Так получаются типы путей, параметров и ответов для TypeScript — их достаточно, чтобы обернуть fetch своими руками и получить проверку типов на каждом вызове.

Генераторы по-разному поддерживают OpenAPI 3.1

Документ объявлен как 3.1.0 и использует его возможности — например, тип-массив ("type": ["string", "null"]) вместо nullable. Генератор, умеющий только 3.0, такие поля разберёт неточно или упадёт. Проверяйте результат, прежде чем закладываться на него в сборке.

Если клиент нужен не для TypeScript, ориентируйтесь на operationId: он уникален у каждой операции и составлен из метода и пути (get_keys, post_keys_id_rotate), поэтому имена функций в сгенерированном клиенте получаются предсказуемыми.

Postman

  1. 1

    Сохраните спецификацию

    curl -s http://localhost:8080/api/v1/openapi.json -o openapi.json
    
  2. 2

    Импортируйте файл

    Import → выберите openapi.json. Postman разложит запросы по тегам: «Песочницы», «Ключи доступа», «Вебхуки», «Журнал запросов» и так далее — это те же группы, что в этом справочнике.

  3. 3

    Подставьте ключ

    Схема авторизации в документе — Bearer. Впишите серверный ключ stend_sk_… в авторизацию коллекции, и он подставится во все запросы.

  4. 4

    Проверьте адрес

    В servers стоит адрес того стенда, с которого скачана спецификация. Если вы качали её с localhost, а работаете с другим стендом — поправьте переменную окружения коллекции.

Чего в спецификации нет

  • Примеров запросов и ответов: examples не заполняются, есть только схемы. Живые примеры — в этом разделе документации.
  • Части кодов отказа. Реестр проставляет общие коды сам, а 409 и 422 маршрут объявляет вручную — и объявлены они не везде: DELETE /webhooks/{id} отвечает 409 при непустом журнале, а DELETE /sandboxes/{sandboxId} — 422 на последней песочнице, хотя в документе этих кодов нет. Сгенерированный клиент отдаст такой ответ как необработанную ошибку транспорта.
  • Заголовков ответа: X-RateLimit-*, Retry-After и X-Truncated в спецификации не описаны, хотя приходят на каждом ответе.

Что в ней, наоборот, учтено: у GET /logs/export успешный ответ объявлен сразу двумя типами содержимого — application/json и text/csv, поэтому сгенерированный клиент не пытается разобрать CSV как JSON.