APIСтандартизация
тема 1
Открыть слайдами →

66API нельзя бесконечно менять без правил

Изменение, безобидное для сервера, может сломать клиента, о котором разработчик не знает.

сегодня
{
  "id": 10,
  "title": "..."
}

Завтра разработчик решает переименовать title → subject. Старый клиент продолжает искать title, получает пустое значение, и интеграция ломается.

Для этого нужны правила совместимости и versioning.

  1. API v1title
  2. rename
  3. API changedsubject
  4. OLD CLIENT ✕

67Не путайте четыре разных номера

В одном проекте одновременно живут четыре независимых номера версии.

OpenAPI Specification version3.1.0

редакция формата, которым описан контракт

API contract version1.4.2

состояние публичного контракта, info.version

Runtime major API version/api/v1

несовместимая редакция, с которой работает клиент

Deployment version4ab219…

commit, из которого собран запущенный код

Это независимые сущности. openapi: 3.1.0 не означает API version 3.1.

68Версию контракта удобно вести как MAJOR.MINOR.PATCH

Semantic Versioning по номеру сразу сообщает, насколько опасно обновление.

1 . 4 . 2
│   │   └ PATCH
│   └──── MINOR
└──────── MAJOR
ЧастьКогда увеличивается
MAJORнесовместимое изменение
MINORсовместимая новая функциональность
PATCHсовместимое исправление

Zalando API Guidelines прямо требуют Semantic Versioning для info.version.

69Что может сломать существующего клиента

Breaking change — изменение, после которого клиент, написанный по старому контракту, перестаёт работать.

breaking
  • удалить endpoint;
  • переименовать endpoint;
  • удалить response field;
  • переименовать field;
  • изменить тип field;
  • добавить обязательный parameter;
  • изменить authentication requirements.
non-breaking
  • добавить endpoint;
  • добавить optional parameter;
  • добавить response field;
  • добавить response header.

GitHub относит именно такие изменения к breaking changes своего REST API — список виден на кадре слайда 72.

70Не каждое изменение требует новой major version

Additive changes только добавляют возможности и не отнимают существующие.

Additive changeПочему старый клиент не ломается
новый endpointстарый клиент его не вызывает
новый optional parameterбез него запрос работает как раньше
новый response fieldклиент читает только известные ему поля
новый response headerнеизвестные заголовки игнорируются

Добавление поля безопасно, только если клиенты игнорируют неизвестные поля. Поэтому конкретная организация должна сама формально определить свою compatibility policy.

  1. OLD CLIENT
  2. NEW API
  3. ✓

71Наш учебный API использует major version в path

Мажорная версия записана прямо в адресе.

/api/v1/tickets

При действительно несовместимом redesign может появиться:

/api/v2/tickets

Это простой и хорошо заметный клиенту способ versioning: версия видна в любом логе и ссылке. Так же поступает Microsoft Graph (/v1.0, /beta), а Azure в той же компании передаёт версию query-параметром api-version — это разобрано на слайде 105.

АдресКто работает
/api/v1OLD CLIENTS
/api/v2NEW CLIENTS

Обе редакции работают одновременно, пока старые клиенты не перейдут на новую.

72URL path — не единственный вариант

GitHub REST API использует версии, названные по дате выпуска, и передаёт их в заголовке.

заголовок запроса
X-GitHub-Api-Version: 2026-03-10

Breaking changes выходят только в новой API version, а совместимые изменения попадают во все поддерживаемые версии. Если заголовка нет, GitHub использует версию по умолчанию.

Versioning strategy — инженерное решение конкретной системы, а не обязательный /v1 для всех API.

docs.github.com · API VersionsСКРИНШОТ · 15.09.2026
GitHub Docs: текущая версия 2026-03-10 и список изменений, которые GitHub считает breaking. Пример с заголовком — ниже, в разделе «Specifying an API version». Клик — увеличить.

73Старое API сначала объявляется устаревшим

Нельзя просто удалить endpoint, который используют клиенты. Удаление проходит несколько стадий.

ACTIVEработает
DEPRECATEDобъявлен устаревшим
MIGRATION PERIODклиенты переходят
SUNSETдата отключения
REMOVEDудалён

OpenAPI позволяет отметить operation:

get:
  operationId: listTicketsOld
  deprecated: true
  description: Используйте GET /api/v2/tickets

Swagger UI зачёркивает такую операцию. Zalando API Guidelines требуют отражать deprecation непосредственно в API specification и описывать путь миграции. Как сообщить об этом в каждом ответе — слайд 106.

74Изменения публичного контракта должны иметь историю

Файл CHANGELOG.md перечисляет изменения, которые касаются потребителей API.

CHANGELOG.md
## [1.1.0]

### Added

- GET /api/v1/tickets/{id}/comments
- optional status filter

### Deprecated

- field old_status

Разделы Added, Changed, Deprecated, Removed, Fixed, Security взяты из соглашения Keep a Changelog.

Changelog предназначен для потребителя API, а не только для разработчика. Рефакторинг, который не меняет контракт, туда не пишут.

Как журнал ведут Stripe и Kubernetes — слайд 100.

75Архитектурное решение тоже является документом

ADR (Architecture Decision Record) — короткий документ об одном принятом решении.

docs/adr/0001-api-versioning.md
ADR
├─ Context       что вынудило решать
├─ Decision      что решили
└─ Consequences  чем за это платим

Например: почему мы выбрали /api/v1, а не custom header? Через год разработчик увидит не только решение, но и причину его появления.

docs/adr/0001-api-versioning.md (фрагмент)
## Decision

Мажорная версия указывается в пути: /api/v1.
Версия контракта ведётся по Semantic
Versioning в info.version.

## Consequences

- Версия видна в любом логе и ссылке.
- Нельзя выпустить несовместимое изменение
  одной операции, не выпуская /api/v2 целиком.

Кадр крупным планом