Тем, кто публикует свой API
Документация провайдера
Как опубликовать API, подключить свой апстрим, назначить тарифы, получать деньги и не сломать интеграции потребителей при обновлении.
Содержание14
- 1Публикация
- 2Апстрим: что мы шлём и чего не шлём
- 3Видимость и модель денег
- 4Версии и ломающие изменения
- 5Тарифы
- 6Отладка и данные клиентов
- 7Кэш ответов
- 8Потоковые вызовы
- 9Наблюдение за вашим API
- 10Свой домен
- 11Снятие с публикации, «устарел» и удаление
- 12Роли в организации
- 13Деньги и выплаты
- 14Что проверить перед публикацией
1Публикация
- 1Создайте API: имя, короткое имя в адресе, адрес вашего апстрима, таймаут, видимость.
- 2Загрузите спецификацию OpenAPI 3. Из неё берётся всё: список операций, мок, песочница, фрагменты кода, SDK и сравнение версий.
- 3Назначьте тарифы.
- 4Опубликуйте. До публикации API виден только вам.
Мастер можно бросить на любом шаге и вернуться позже: черновик остаётся, ссылка на него есть в консоли провайдера. Незаконченный API не показывается никому и ничего не стоит.
- Спецификация разбирается без обращений по внешним ссылкам: $ref внутри документа работают, ссылки на чужие адреса — нет. Скачивать по ссылке из чужого файла значит ходить в сеть от нашего имени по чужому указанию.
- Короткое имя API становится первым сегментом пути: /v1/ваше-имя/…. Менять его после публикации нельзя — это сломало бы всех, кто уже вызывает.
- Мок отвечает примерами из спецификации. Чем подробнее примеры, тем полезнее песочница: путь от «нашёл API» до первого ответа — это то, где вас выбирают или не выбирают.
2Апстрим: что мы шлём и чего не шлём
| Что | Как |
|---|---|
| Авторизация у вас | Заголовок, параметр запроса или ничего. Секрет шифруется и в ответах API площадки не показывается |
| X-Forwarded-For | Настоящий адрес вызывающего, а не наш |
| X-Request-Id | Идентификатор вызова — тот же, что видит потребитель и что стоит в нашей трассе |
| Заголовки потребителя | Проходят как есть, кроме X-API-Key и Authorization: ваш ключ доступа к вам мы не пересылаем чужому |
| Таймаут | Ваш, из настроек API. По его истечении потребитель получает upstream_timeout, и вызов не тарифицируется |
Тело и строка запроса передаются без изменений, включая исходное кодирование пути: перекодировать то, что клиент уже экранировал, значит молча изменить запрос, который вы получите.
3Видимость и модель денег
| Видимость | Кто видит | Как идут деньги |
|---|---|---|
| PUBLIC | Все, включая поиск | Через площадку: мы выставляем счёт потребителю и платим вам за вычетом комиссии |
| PARTNER | Только организации, которым вы выдали доступ | Через площадку |
| PRIVATE | Только вы | Ваш собственный биллинг: мы считаем вызовы и берём плату за обслуживание |
Модель выводится из видимости, и отдельно её не выбирают. Решение открытое и с симметричной ценой: ушли из публичного каталога — потеряли витрину, начали платить за инфраструктуру. Значения по умолчанию у денежного поля нет нигде: однажды такое умолчание сделало расчёт холостым, и обнаружилось это только на прогоне в миллион вызовов.
- Доступ партнёру выдаётся по короткому имени его организации и сопровождается заметкой — через полгода по ней вспомнят, за что он выдан.
- Отзыв доступа гасит подписки партнёра сразу. Гасит, а не удаляет: всё, что он уже отработал, останется в счёте. Иначе отзыв был бы способом не выставлять счёт.
- Смена видимости с публичной на партнёрскую не отбирает доступ у тех, кто уже подписан: это решение о витрине, а не о действующих договорённостях.
4Версии и ломающие изменения
При загрузке новой версии мы сравниваем её с предыдущей по смыслу, а не по тексту: переписанное описание, другой порядок ключей и переформатирование изменением не считаются.
| Изменение | Ломает | Почему |
|---|---|---|
| Удалён путь или операция | Да | Вызовы упираются в 404 |
| Новый обязательный параметр запроса | Да | Ломает всех, кто его не шлёт |
| Поле пропало из ответа | Да | Читающий его получает пустоту |
| Сменился тип поля | Да | Разбор на стороне потребителя падает |
| Удалён код ответа | Да | Обработчик этого кода перестаёт вызываться |
| Удалён способ авторизации | Да | Настроенная интеграция перестаёт проходить |
| Новое необязательное поле в ответе | Нет | Кто не знает о нём, тот его не читает |
| Новое значение перечисления в ответе | Да | switch без ветки по умолчанию встретит незнакомое |
| Убрано значение перечисления из запроса | Да | Тот, кто его слал, получит отказ |
- Ломающее изменение требует новой мажорной версии. Выпуск под минорной отклоняется с перечислением того, что именно сломается, — не общим «есть несовместимости».
- Changelog собирается из сравнения, если вы не написали его сами. Написанное руками мы не трогаем.
- Подписчикам уходит отдельное событие о поломке, а не признак внутри «вышла версия»: событие, которое надо разворачивать, чтобы понять его важность, читают вполглаза.
- Сравнение двух любых версий доступно и потребителю на странице API — он видит то же, что вы, и до перехода, а не после.
5Тарифы
| Поле | Что задаёт |
|---|---|
| Цена | Абонплата за месяц. Берётся, даже если вызовов не было |
| Квота | Включённые вызовы за месяц. Пусто — без ограничения |
| Лимит в секунду | Частота. Защищает ваш апстрим, а не наш |
| Цена перерасхода | Сколько стоит вызов сверх квоты на мягком тарифе |
| Жёсткий лимит | Да — 429 на границе квоты; нет — пропускаем и тарифицируем перерасход |
- Правка тарифа не меняет условия задним числом: у тарифа есть версии, и период считается по той, что действовала.
- Смена тарифа посреди месяца делит абонплату и квоту по дням.
- Бесплатный тариф — обычный тариф с нулевой ценой. Он же ваш главный инструмент: в кабинете видно, сколько потребителей перешло с него на платный.
- Тариф, на который есть подписки, нельзя удалить — только скрыть от новых подписок.
6Отладка и данные клиентов
Захват заголовков и тел выключен по умолчанию и включается вами. Это единственное место, где «выключено» и есть правильное умолчание: включённый захват означал бы, что площадка начала хранить данные ваших клиентов, никого не спросив.
- Заголовки авторизации вырезаются всегда. Свои чувствительные поля перечислите отдельно — они не попадут в запись вовсе, а не будут замазаны при показе.
- Записывается выборка успешных вызовов и все ошибочные: отлаживают именно неудачные.
- Тела сжимаются и шифруются, именно в таком порядке: шифротекст неотличим от случайных байтов, а те не сжимаются.
- Срок хранения задаётся вами, в тарифе: от часа до года, по умолчанию час. Это условие тарифа, а не настройка отладки — от него зависит и то, за что платит потребитель, и то, сколько данных ваших клиентов лежит у нас. Правка срока рождает новую версию тарифа, а действующие подписки остаются на прежней.
Дайте потребителю проверить обработку отказов
curl 'https://apihub.tw1.su/v1/ваш-api/метод' \ -H 'X-API-Key: ahk_test_…' \ -H 'X-Sandbox-Chaos: latency=2000,error=503,rate=0.3'
Заголовок действует только на моках — на тестовых ключах и анонимных пробах. Подмешивать ошибки в настоящий трафик нельзя никому: это был бы способ вредить.
7Кэш ответов
Площадка умеет отдавать повторный ответ из памяти, не тревожа ваш апстрим. Кэшируемость объявляете вы, в самой спецификации: мы не угадываем, что у вас меняется раз в сутки, а что каждую секунду.
Объявление в операции
/lookup:
get:
x-apihub-cache:
ttl: 86400 # сколько секунд ответ можно отдавать повторно
vary: [code] # по каким параметрам строится ключ- Без объявления не кэшируется ничего. Два соседних пути одного сервиса ведут себя по-разному, и по виду ответа их не различить: справочник живёт сутками, «сколько сейчас времени» не живёт вовсе.
- Кэшируется только GET и только ответ 200. Заголовок Cache-Control: no-store, no-cache или private в вашем ответе отменяет кэширование этого конкретного ответа: объявление — про операцию вообще, заголовок — про этот раз.
- Без vary в ключ идут все параметры запроса. Лишний параметр в ключе даёт лишний промах, недостающий — чужой ответ; умолчание ошибается в безопасную сторону.
- Ключ общий для всех потребителей — в этом и смысл. Поэтому кэшируемым объявляйте только то, что одинаково для всех: ответ, зависящий от вызывающего, объявлять нельзя.
- Выпуск новой версии обесценивает кэш сам: версия входит в ключ, и старые ответы просто перестают находиться.
- Попадание помечено заголовком X-Apihub-Cache: hit — и у потребителя, и в трассе.
8Потоковые вызовы
Площадка проксирует Server-Sent Events и WebSocket. У таких вызовов нет ответа, который когда-нибудь кончится, и почти всё, на чём держится обычный путь, к ним неприменимо — поэтому и правила у них свои.
| Что | Как |
|---|---|
| SSE | Определяется по спецификации: у операции в ответе объявлен text/event-stream |
| WebSocket | По заголовку Upgrade в запросе; спецификация его не описывает |
| Таймаут | Таймаут вашего API к потоку не применяется: он про «сколько ждать ответа» |
| Захват тел | Выключен: запись собирается до конца ответа, а конца может не быть |
| Кэш | Не применяется |
| Единица счёта | Минута соединения, цена задаётся в тарифе |
- Минуты считаются по ходу соединения, а не в конце: соединение на четыре часа, посчитанное в момент разрыва, теряется целиком при перезапуске шлюза. Первая минута начисляется сразу — минута начата, минута оплачена.
- Само соединение тарифицируемым вызовом не является: за него платят минутами, иначе час потока стоил бы минуты плюс вызов сверху.
- Квоту в вызовах минуты не расходуют. Час соединения — это не шестьдесят запросов.
- В отличие от попадания в кэш минуты делятся с вами как обычный вызов: соединение обслуживает ваш сервис, работа настоящая.
- Число одновременных соединений на подписку ограничено. Открытое соединение занимает память и дескриптор, и один потребитель с циклом переподключения иначе занимает шлюз целиком.
9Наблюдение за вашим API
Площадка сама проверяет ваш API пробами и показывает результат отдельным разделом, рядом с общей статистикой, но не смешиваясь с ней: одно — то, что видели пользователи, другое — то, что видели мы. Скрыть этот раздел нельзя, иначе он не значил бы ничего.
- Путь пробы берётся из спецификации: первая операция без обязательных параметров. Если такой нет, задайте путь сами — выдумывать значения за вас мы не станем.
- Ответы 4xx считаются признаком работающего сервиса: 401 у API с авторизацией — это ответ, а не отказ.
- «Данных мало» — отдельный статус, а не пустое место: молчание читалось бы как «плохо».
- Наблюдение можно обнулить, но только при выпуске новой версии. Факт выпуска мы видим сами, верить на слово не нужно, а число сбросов показывается рядом с показателем.
- Бейдж для README отдаётся картинкой и кэшируется на пять минут.
10Свой домен
Каталог можно показывать под своим именем: api.вашакомпания.ru вместо страницы внутри площадки. Порядок повторяет порядок в жизни: заявить домен, опубликовать TXT-запись, подтвердить.
- Кнопка подтверждения не прячется до появления записи в DNS: когда ваша зона обновилась, знаете вы, а не мы.
- Название, логотип и основной цвет задаются там же. Пустое значение означает «берите оформление площадки», а не пустоту.
- Автовыпуск сертификата на домены провайдеров пока не сделан — это записанный долг, и мы говорим об этом до того, как вы настроите DNS.
11Снятие с публикации, «устарел» и удаление
Три разных действия, и путать их дорого: у каждого своя судьба тех, кто уже подписан.
| Действие | Что с каталогом | Что с подписчиками |
|---|---|---|
| Снять с публикации | Уходит из каталога и из шлюза | Вызовы прекращаются: у подписчиков api_not_found. Подписки остаются и продолжают тарифицироваться абонплатой |
| Пометить «устарел» | Остаётся в каталоге с пометкой | Продолжают работать как прежде |
| Удалить | Исчезает совсем | Отказ, пока подписан хоть кто-то |
12Роли в организации
| Роль | Что может у провайдера |
|---|---|
| OWNER | Всё, включая деньги: выплаты, доход, тарифы |
| ADMIN | Всё, кроме владения организацией |
| DEVELOPER | API, версии, спецификации, отладка. Денег не видит |
Позвать сотрудника — на экране «Сотрудники»: адрес и роль, дальше вы передаёте ссылку сами. Приглашение именное и работает только у того, кто вошёл под указанным адресом; подробности — в документации потребителя, раздел про приложения и роли: механизм общий для обеих сторон.
13Деньги и выплаты
- Вам платят за вызовы, которые обслужил ваш апстрим. Отказ на нашей стороне, ваша же пятисотка, таймаут и ответ из мока не тарифицируются.
- Ошибка в запросе потребителя (4xx от вас) тарифицируется: вы её обработали.
- Расчёт помесячный и только после того, как сошлась сверка. Не сошлась — ничего не выставляется, пока не разберёмся.
- Выплата разделена на намерение и факт: подготовленная выплата не двигает книгу, проводка появляется, когда деньги ушли и есть номер поручения.
- Комиссия площадки видна рядом с заработанным. Показать доход без неё значило бы разойтись с тем, что вы увидите у себя в выручке, и объясняться потом.
- В кабинете виден доход по дням, топ-потребители и переход с бесплатного тарифа на платный.
14Что проверить перед публикацией
- 1Спецификация содержит примеры ответов у основных операций: по ним работают мок и песочница, а это первое, что увидит потребитель.
- 2Есть операция без обязательных параметров — или задан путь пробы вручную, иначе наблюдение не запустится.
- 3Таймаут выставлен по вашему настоящему времени ответа, а не «на всякий случай побольше»: он определяет, когда вызов перестанет тарифицироваться.
- 4Бесплатный тариф решён осознанно: с ним пробуют, без него уходят к тому, у кого он есть.
- 5Чувствительные поля перечислены в настройках захвата — до того, как захват включён, а не после.
- 6Апстрим доступен снаружи и не ограничен по адресу так, что наш шлюз в него не попадёт.