Changelog и политика версий¶
Страница для интегратора: как меняется контракт и на что можно опираться.
Текущая версия¶
openapi.yaml 0.3.2 — контракт до передачи первому интегратору. Пока
версия ниже единицы, ломающие изменения возможны и объявляются заранее.
При передаче контракт замораживается как v1.0.0-rc, и дальше действует
правило ниже.
Что можно и чего нельзя после заморозки¶
Аддитивные изменения — можно в любой момент, без предупреждения:
- новое необязательное поле в ответе;
- новое значение в перечислении (
error.code,reason_code, тип события); - новая ручка;
- новый необязательный параметр запроса.
Клиент обязан быть к ним готов: игнорировать незнакомые поля и типы событий. Приёмник, падающий на новом типе события, сломается на первой же безобидной правке.
Ломающие изменения — только с новой версией пути (/v2) и сроком, за
который переезжают:
- удаление или переименование поля;
- изменение типа поля;
- новое обязательное поле в запросе;
- сужение перечисления;
- изменение смысла существующего значения.
Проверяется это не обещанием, а гейтом: каждое изменение спеки, пришедшее через merge request, сравнивается с предыдущей версией автоматически, и ломающее изменение не проходит сборку. Сам гейт тоже проверяется — заведомо сломанная спека обязана его уронить, иначе зелёная сборка означала бы лишь то, что сравнение не работает.
Устаревание¶
Поле или ручка помечается устаревшей в спеке (deprecated: true) и продолжает
работать. Срок жизни устаревшего — не меньше 90 дней с момента, когда об
этом сообщили; удаление — только с новой версией пути.
Как узнать, что изменилось¶
- сама спека —
api/openapi.yamlв репозитории хаба, версия в полеinfo.version; - отличия между версиями — машинным сравнением (
oasdiff) между тегами; - существенные изменения поведения — на этих страницах руководства; таблицы кодов и причин в них генерируются из реестров в коде, поэтому не отстают от поведения хаба.
История¶
| Версия | Что изменилось |
|---|---|
| 0.3.3 | поведение без изменения схем, которое раньше не попало в историю: одноразовый код, публикацию которого не подтвердил брокер, получает 503 provider_unavailable вместо 202 (сервисное — по-прежнему 202, его доставит сборщик; в пакете такой код становится rejected); отказ хранилища или шины — 503 с retry_after вместо 500; перекрытия batch_max и api_rps аккаунта теперь применяются, api_rps считается на ключ; у сообщения старше срока хранения номера поле to пустое. Исправлены описания: send_at в MVP не поддерживается (любое значение — 422 send_at_not_supported), секрет подписи хранится зашифрованным, а не хешем. Совет по причине dlr_timeout — «повторить позже»: это отказ оператора, поздний отчёт по нему не придёт; ждать позднего отчёта имеет смысл только при dlr_timeout_local. Текст duplicate_rejected — про шаблон с занятым именем: повтор сообщения этот код не получает |
| 0.3.2 | вебхуки: автоотключение подписки больше не теряет недоставленное — батч, на котором она отключилась, и события за время простоя копятся и доставляются после POST /webhook_endpoints/{id}/enable в пределах 24 ч от события; подписка отключается только когда отказы идут подряд не меньше часа (раньше — по 20 отказам, что под трафиком наступало за минуты). Схемы не менялись |
| 0.3.1 | Sender.registration был объявлен массивом per-оператор, а admin-api всегда писал плоский объект — send-api молча терял данные при разборе (GET /account, GET /senders). Приведено к факту: registration — объект произвольной формы (даты переписки с оператором); multi-operator форма не нужна на MVP (один оператор — МегаФон) |
| 0.3.0 | подписки на вебхуки (CRUD, ротация секрета, пробная доставка, журнал попыток), песочница с магическими номерами, пакеты, оценка стоимости, девять новых кодов ошибок, секция исходящих вебхуков; причина ttl_expired_before_submit — отделена от dlr_timeout_local, чтобы «не отправляли» отличалось от «отправили и не дождались отчёта» |
| 0.2.0 | сверка с руководством оператора: срок жизни на нашей стороне, отказ приходит с HTTP 200, прочтение не статус, ручной модерации шаблонов |
| 0.1.0 | первый скелет контракта по итогам дизайн-сессии |