Версионирование и изменения контрактов

↑ 1.6 Документация API: Swagger и OpenAPI · ← Предыдущая

Обязательно~5 мин чтенияУровень: junior

Зачем это аналитику и PM

Поле, которое вчера было строкой, сегодня нельзя молча сделать числом. Клиенты уже выпустили свои программы. Изменение контракта либо совместимо со старым вызовом, либо это отдельное решение со сроком.

План темы

  • breaking и non-breaking изменения
  • депрекейшн
  • как сообщать клиентам

Объяснение

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

Как правило в подъезде. Новая строка «можно ещё так» никому не мешает. Строка «старый ключ больше не подходит» требует объявления и срока, иначе жильцы останутся у двери.

Что ломает, а что нет

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

Новое значение в перечислении — серая зона. Клиент, который отвергает незнакомые значения, сломается. Если такие клиенты есть, это ломающее изменение, даже если серверу «всего лишь добавили статус».

Номер в info.version — версия документа. Кусок /v1 в адресе — версия, которую вызывает клиент. Это не одно и то же. Смена только номера в шапке не сохраняет старый адрес.

Устаревший метод помечают, а не стирают в тот же день. В OpenAPI 3.0 у операции есть признак deprecated. Рядом пишут, чем заменить и до какой даты старый путь ещё жив. Дату берёт команда, не эта заметка.

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

flowchart TD
    A["Изменение контракта"] --> B{"Старый клиент ещё работает"}
    B -->|"да"| C["Та же версия адреса"]
    B -->|"нет"| D["Срок и замена"]

Примеры

Пометка устаревшего чтения. Файл версии 3.0.3. Дата в тексте условная, её подставляет команда.

openapi: "3.0.3"
info:
  title: Example Orders
  version: "1.1.0"
paths:
  /orders/legacy/{orderId}:
    get:
      deprecated: true
      summary: Устаревшее чтение заказа
      description: Замена — GET /orders/{orderId}. Срок снимают отдельно, не этим примером.
      responses:
        "200":
          description: Заказ
ИзменениеДля старого клиента
Новое необязательное полеобычно незаметно
Поле стало обязательнымломает
Новое значение перечисленияможет сломать строгого клиента

Нюансы и подводные камни

  • «Мы добавили поле» ломает, если оно обязательное. Смотрят на required, не на глагол в чате.
  • Две версии без владельца старой живут вечно и расходятся. У старой есть дата или явный наследник.
  • Прятать ломку в том же пути хуже, чем новый путь. Клиент не узнает о смене типа, пока не упадёт.
  • Журнал «исправили контракт» без списка полей нечего тестировать.

Практика

Возьмите одно изменение: поле комментария было необязательным и стало обязательным. Напишите, ломающее ли оно, и одну фразу для клиентов.

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

Вопросы с ответами

Связано с блоком Developer

Связанные темы