Изменение, безобидное для сервера, может сломать клиента, о котором разработчик не знает.
сегодня
{
"id": 10,
"title": "..."
}
Завтра разработчик решает переименовать title → subject. Старый клиент продолжает искать title, получает пустое значение, и интеграция ломается.
Для этого нужны правила совместимости и versioning.
API v1title
rename
API changedsubject
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.
OLD CLIENT
NEW API
✓
71Наш учебный API использует major version в path
Мажорная версия записана прямо в адресе.
/api/v1/tickets
При действительно несовместимом redesign может появиться:
/api/v2/tickets
Это простой и хорошо заметный клиенту способ versioning: версия видна в любом логе и ссылке. Так же поступает Microsoft Graph (/v1.0, /beta), а Azure в той же компании передаёт версию query-параметром api-version — это разобрано на слайде 105.
Адрес
Кто работает
/api/v1
OLD CLIENTS
/api/v2
NEW 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 целиком.