REST APIГайд для аналитиков

Обратная совместимость API

Меняем API, не ломаем клиентов

Автор: Екатерина Ананьева, основатель сообщества системных аналитиков GetAnalyst
Скачать PDF PDF · 4 страницы A4 · 0,3 МБ
Первая страница PDF-гайда «Обратная совместимость API»: заголовок, оглавление и таблица изменений API

Обратная совместимость API — это когда клиенты, написанные под предыдущую версию, продолжают работать после изменений на сервере и не требуют доработки. Ниже — таблица изменений с примерами: что можно менять спокойно, а что ломает клиентов.

Выпуск новой версии API — это всегда головная боль:

  1. 1Нужно уведомить всех клиентов
  2. 2Поддерживать две версии параллельно
  3. 3Дождаться перехода всех на новую версию API
  4. 4И только потом выводить старую версию API из эксплуатации

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

Как это сделать? Смотрите рекомендации в нашем гайде.

Как пользоваться

Прежде чем вносить изменение в действующий API-метод, пройдитесь по таблице. Нашли своё предполагаемое изменение? Смотрите, что делать, чтобы избежать головной боли.

Таблица изменений API: что совместимо, а что ломает клиентов

Всё окклиенты продолжат работать как раньше
Зависитзависит от того, как написаны клиенты
Ломаетчасть клиентов перестанет работать
Изменение в API-методеПримерОбратная совместимостьКак реализовать
1
Изменение в API-методе

Новое необязательное поле или вложенный объект

Пример
Было
POST /orders
{ "items": [ … ] }
Стало
POST /orders
{ "items": [ … ],
  "comment": "Позвонить" }
Обратная совместимостьВсё ок

Старые клиенты продолжают работать как раньше.

Как реализовать
  • Клиенты API должны игнорировать незнакомые поля: это нормальная практика, зафиксируйте её в требованиях для клиентов.
  • В методах создания и изменения задайте значение по умолчанию: если поле не передали, поведение остаётся прежним.
  • Добавьте новое поле в ответы всех ключевых методов ресурса: получение, список, создание, изменение.
2
Изменение в API-методе

Новое значение enum в ответе

Пример
Было
GET /orders/17
{ "status": "SHIPPED" }
Стало
GET /orders/17
{ "status": "REFUNDED" }
  • Клиент без обработки нового статуса упадёт с ошибкой или покажет пустой экран.
  • Клиент с обработкой неизвестных значений покажет «Неизвестный статус».
Обратная совместимостьЗависит

Ок при условии, что все клиенты умеют обрабатывать незнакомые значения.

Как реализовать
  • Заранее закладывайте в клиентах обработку неизвестных значений enum: показывайте «Неизвестный статус» вместо падения.
  • Особенно критично для интеграций с внешними системами. Даже если вас не предупредили, закладывайте обработку неизвестных значений и пишите алерты в логи: внешние вендоры не всегда сообщают об изменениях.
3
Изменение в API-методе

Переименование значения enum

Пример
Было
"status": "CANCELED"
Стало
"status": "CANCELLED"
Безопасно
enum:
  - CANCELED   # deprecated
  - CANCELLED
Обратная совместимостьЛомает

Клиенты, которые ждут старое значение, не узнают новое.

Как реализовать
  • Добавьте новое значение рядом со старым, старое пометьте как deprecated.
  • Переводите клиентов постепенно: по логам видно, кто ещё использует старое значение.
  • Не удаляйте старое значение, пока все клиенты не перейдут на новое.
4
Изменение в API-методе

Смена типа поля

число → строка

Пример
Было
"userId": 1001
Стало
"userId": "1001"
Безопасно
"userId": 1001,
"userIdStr": "1001"

Так сделал Twitter: числовой id остался, рядом добавили строковый id_str.

Обратная совместимостьЛомает

Клиент ждёт число, а получает строку: ошибка разбора или неверное сравнение.

Как реализовать
  • Добавьте новое поле с новым типом рядом со старым, старое пометьте как deprecated.
  • Не удаляйте старое поле, пока все клиенты не перейдут на новое.
  • Тип существующего поля «на месте» не меняйте.
5
Изменение в API-методе

Новый обязательный параметр или более строгая валидация

Пример
Было
POST /orders
{ "items": [ … ] }
Стало
POST /orders
{ "items": [ … ],
  "deliveryType": "COURIER" }
Безопасно
deliveryType:
  type: string
  default: COURIER

deliveryType теперь обязателен: без него сервер вернёт 400.

Обратная совместимостьЛомает

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

Как реализовать
  • Выпустите новую версию API, в которой параметр обязательный.
  • Или сделайте параметр необязательным: со значением по умолчанию и валидацией, чтобы старые клиенты продолжали работать.
  • Когда все клиенты начнут передавать параметр, сделайте его обязательным в новой версии API.
6
Изменение в API-методе

Переименование или удаление поля

Пример
Было
{ "name": "Анна" }
Стало
{ "firstname": "Анна" }
Безопасно
{ "name": "Анна",
  "firstname": "Анна" }
Обратная совместимостьЛомает

Клиент читает name, получает пустое значение и показывает пустое имя.

Как реализовать
  • Отдавайте оба поля с одним значением: старое name и новое firstname. В запросах принимайте оба.
  • Старое поле пометьте как deprecated (deprecated: true в OpenAPI) и объявите дату отключения.
  • По логам смотрите, кто ещё читает старое поле.
  • Удаляйте старое поле только после даты Sunset (см. ниже).
7
Изменение в API-методе

Смена формата даты

Пример
Было
"createdAt": "25.12.2026"
Стало
"createdAt": "2026-12-25"
Безопасно
"createdAt": "25.12.2026",
"createdDate": "2026-12-25"
Обратная совместимостьЛомает

Клиентский парсер ждёт ДД.ММ.ГГГГ и не разберёт новую строку.

Как реализовать
  • Добавьте новое поле с датой в новом формате, старое пометьте как deprecated. Либо выпустите новую версию API.
  • В OpenAPI указывайте формат явно: format: date для даты (ГГГГ-ММ-ДД), format: date-time для даты со временем (RFC 3339).
8
Изменение в API-методе

Смена уровня иерархии

поля переехали во вложенный объект

Пример
Было
{ "id": 42,
  "city": "Казань",
  "country": "RU" }
Стало
{ "id": 42,
  "address": {
    "city": "Казань",
    "country": "RU" } }
Безопасно
{ "id": 42,
  "city": "Казань",
  "country": "RU",
  "address": {
    "city": "Казань",
    "country": "RU" } }
Обратная совместимостьЛомает

Клиент ищет city и country в корне и не находит.

Как реализовать
  • Добавьте объект address с теми же значениями. city и country в корне оставьте и пометьте как deprecated.
  • Какое-то время отдавайте данные в обоих местах, а в запросах принимайте оба варианта.
  • По логам следите, кто ещё читает поля из корня, и удалите их после даты Sunset.

Где хранить версию API

Версия должна где-то жить. Выберите один способ и зафиксируйте его в требованиях.

В URL

/v2/orders

Версия видна в любой ссылке, логе и документации. Минус: у всех методов меняется адрес.

В заголовке

X-GitHub-Api-Version: 2022-11-28Stripe-Version: 2026-09-30.endive

Адреса методов не меняются. Так делают GitHub и Stripe: версия обозначена датой.

Что записать в требованиях

  • Где передаётся версия: в URL или в заголовке.
  • Какая версия применяется, если клиент её не передал. У GitHub это 2022-11-28.
  • Сколько версий поддерживаем параллельно. GitHub держит предыдущую версию не меньше 24 месяцев после выхода новой.

Как выводить старую версию из эксплуатации

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

1 января 2027Deprecation: версию объявили устаревшей
Обе версии работают, клиенты переходят, вы смотрите логи. В этом примере на переход отведено полгода.
1 июля 2027Sunset: старую версию отключили
  1. 1

    Объявили

    Deprecation: @1798761600Link: <https://api.example.com/migrate-v2>; rel="deprecation"

    Версия устарела с 1 января 2027 (RFC 9745). В ссылке — инструкция по миграции. Напишите клиентам и добавьте запись в changelog.

  2. 2

    Назначили дату

    Sunset: Thu, 01 Jul 2027 00:00:00 GMT

    Плановое отключение (RFC 8594). Дата Sunset не раньше даты Deprecation.

  3. 3

    Проверили по логам

    Посмотрите, кто ещё вызывает старую версию, и напишите этим клиентам лично до даты отключения.

  4. 4

    Отключили

    410 Gone

    После Sunset старая версия отвечает 410 Gone со ссылкой на новую.

Частые вопросы про обратную совместимость API

Что такое обратная совместимость API?

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

Какие изменения API обратно совместимы?

Безопасно добавлять необязательные поля, вложенные объекты и параметры со значением по умолчанию. Новое значение enum в ответе совместимо, если все клиенты умеют обрабатывать неизвестные значения. При этом клиенты должны игнорировать незнакомые поля.

Какие изменения API ломают клиентов?

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

Как переименовать поле в API и не сломать клиентов?

Отдавайте оба поля с одним значением: старое name и новое firstname. В запросах принимайте оба. Старое поле пометьте как deprecated, по логам смотрите, кто его ещё читает, и удалите после даты Sunset.

Где хранить версию API: в URL или в заголовке?

Подходят оба способа. В URL версия видна в любой ссылке, но у всех методов меняется адрес (/v2/orders). В заголовке адреса не меняются: так делают GitHub (X-GitHub-Api-Version) и Stripe (Stripe-Version). Выберите один способ и зафиксируйте его в требованиях.

Как объявить, что версия API устарела?

Отправляйте заголовок Deprecation (RFC 9745), добавьте в Link ссылку на инструкцию по миграции с rel="deprecation" и назначьте дату отключения заголовком Sunset (RFC 8594). После даты Sunset старая версия отвечает 410 Gone.

Екатерина Ананьева

Основатель сообщества системных аналитиков GetAnalyst

Екатерина Ананьева — основатель сообщества системных аналитиков GetAnalyst. Системный аналитик с опытом более 10 лет на крупных IT-проектах, преподаватель и автор подкаста GetAnalyst. Пишет про REST API, интеграции и архитектуру.

GetAnalyst

Гайд «Обратная совместимость API»

4 страницы A4: таблица изменений с примерами, хранение версии и вывод старой версии из эксплуатации. Откройте на следующем API-review.

Скачать PDF PDF · 4 страницы A4 · 0,3 МБ

Разборы по API и архитектуре — в Telegram-канале @getanalysts

Бесплатное обучение

Получайте полезные материалы и учитесь новому каждый день в наших социальных сетях.

Youtube
Rutube
Linkedin
VK
Habr
Blog
Podcast


VK

Контакты

+7 (499) 686-15-46

Лицензия №Л035-01255-50/01366872 от 28.08.2024

VK
VK

Практический опыт здесь, 2021-2026

Индивидуальный предприниматель
Алтунин Дмитрий Михайлович
ИНН 503610364488

Мы используем файлы cookie, для персонализации сервисов и повышения удобства пользования сайтом. Если вы не согласны на их использование, поменяйте настройки браузера.