Мы часто видим номера версий в сторонних API, но не задумываемся о внутренней кухне версионирования: как делать и для чего? Рассмотрим best practice.
❓Когда версионировать API?
API нуждается в версионировании, когда происходят значительные изменения, влияющие на поведение или контракт API:
- Добавляются новые обязательные поля.
- Меняется формат возвращаемых данных.
- Удаляются старые свойства или изменяется логика работы API.
- Изменяется семантика методов (например, ранее GET запрашивал список объектов, теперь возвращается агрегационная статистика).
🔑 Способы версионирования REST API
Существует несколько популярных способов версионирования API:
☝️ Версификация через URL
Один из самых распространённых способов — включение номера версии непосредственно в URL. Например:
GET /api/v1/products
GET /api/v2/products
Преимущества:
- Простота реализации.
- Легко различимые версии API.
Недостатки:
- Нарушает чистоту концепции REST, поскольку URI должны идентифицировать ресурс, а не его версию.
- Могут возникать сложности при изменении URL структуры (например, смена префикса или удаление старого маршрута).
✌️ Версификация через заголовок HTTP
Альтернативный вариант — размещение версии API в специальном заголовке HTTP, например:
Accept: application/vnd.mycompany.v1+json
Content-Type: application/json
или
X-Api-Version: v2
Преимущества:
- Более чистое решение с точки зрения REST.
- Сохраняет единство ресурсов и независимость от URL.
Недостатки:
- Требуется дополнительная настройка обработчиков заголовков на стороне сервера.
- Клиенты должны помнить о необходимости отправки правильного заголовка.
🤟 Версификация через Content Type
Можно указывать версию API в MIME-типе, например:
Accept: application/vnd.mycompany.products-v1+json
Преимущества:
- Четкое разделение ресурсов и версий.
- Может сочетаться с Content Negotiation.
Недостатки:
- Сложность понимания пользователями, привыкшими видеть номер версии в URL.
- Необходимость поддерживать обработку нескольких Content Types.
💣 Лучшие практики версионирования REST API
1. Обеспечьте обратную совместимость. Всегда старайтесь минимизировать влияние изменений на существующие клиенты. Постепенный переход на новую версию API позволит снизить риски отказа сторонних систем.
2. Четкая документация каждой версии. Каждый релиз новой версии API должен сопровождаться подробной документацией с описанием всех изменений и возможных последствий для клиентов.
3. Ограничьте число активных версий. Со временем устаревшие версии API стоит удалять, уведомив заранее клиентов о сроках прекращения поддержки старых версий.
4. Используйте фазовый вывод старой версии. Постепенно отключайте старую версию API, давая достаточное время для миграции клиентов на новую версию.
5. Тестируйте каждую версию отдельно. Перед выпуском новых версий убедитесь, что старая версия продолжает стабильно функционировать.
6. Создавайте тесты на совместимость. Регулярные проверки API позволят выявить возможные регрессии и убедиться, что новая версия API не ломает старый код.
🪧 Итог 🪧
Выбор способа версионирования зависит от конкретной ситуации и требований проекта. Наиболее распространённый подход — версионирование через URL, однако он имеет ряд недостатков с точки зрения чистоты REST. Альтернатива в виде версионирования через заголовки или Content Type предоставляет больше гибкости и соответствует идеям RESTful дизайна. Независимо от выбранного подхода, ключевое значение имеют продуманность изменений, хорошая документация и обеспечение постепенного вывода старых версий API.