0% прочитано

Чому версія API і версія продукту - не одне й те саме

У складній системі одночасно можуть існувати версія продукту, API, протоколу інтеграції та формату даних. Пояснюю, чому я не намагаюся звести їх до одного номера і яке питання сумісності вирішує кожна версія.

2 жовтня 2026 р. 8 хв читанняЛаравель

У складнішій системі слово "версія" дуже швидко перестає означати щось одне.

Може бути версія самого застосунку. Окремо - версія зовнішнього API. Ще окремо - версія протоколу взаємодії або формату даних.

Спочатку є спокуса використати один номер для всього. Наприклад, продукт має версію 3.4.0, отже і API ніби теж "версії 3".

Але ці числа відповідають на різні питання.

Під час проєктування інтеграцій я використовую просте правило: якщо дві версії можуть змінитися незалежно одна від одної, це дві різні версії.

Версія має сенс лише разом із тим, що саме вона версіонує.

В одній системі може бути кілька незалежних версій

Кілька версій одного продукту
Застосунок    version 4.8.2 Зовнішній API    v2 Протокол інтеграції    version 3 Формат даних    schema version 5

Ці чотири числа не суперечать одне одному.

Вони описують різні частини системи:

  • версія застосунку описує конкретний випуск програмного забезпечення;
  • версія API описує зовнішній контракт для клієнтів;
  • версія протоколу описує правила взаємодії між сторонами;
  • версія схеми описує форму певного набору даних.

Новий випуск застосунку не обов’язково означає новий API. І новий формат даних не обов’язково вимагає випуску нової основної версії API.

Версія продукту відповідає на питання: що зараз встановлено

Версія застосунку зазвичай пов’язана з випусками самого програмного забезпечення.

У новій версії можуть з’явитися:

  • внутрішній рефакторинг;
  • виправлення помилок;
  • нові можливості;
  • зміни інтерфейсу;
  • оновлення залежностей;

При цьому зовнішній контракт API може залишитися абсолютно таким самим.

Наприклад, між 4.8.2 та 4.9.0 можна повністю змінити внутрішню реалізацію певного сценарію, не змінюючи жодного поля запиту чи відповіді.

Версія API відповідає за зовнішній контракт

Версія API потрібна не для того, щоб показати номер поточного випуску застосунку.

Вона потрібна для сумісності зовнішніх клієнтів.

Коли клієнт працює з певною основною версією API, він очікує, що задокументовані правила цієї версії залишаються дійсними.

Наприклад, без порушення контракту я можу:

  • виправити внутрішню помилку;
  • оптимізувати запит до бази;
  • перенести логіку між класами;
  • оновити Laravel;
  • змінити спосіб кешування.

Жодна з цих змін сама по собі не є причиною створювати нову основну версію API.

Кілька випусків можуть використовувати той самий API
Product releases: 4.7.0  |4.8.0  |4.8.1  |4.9.0  |5.0.0  Public API: v2

Версія протоколу описує правила взаємодії

Іноді поверх HTTP API існує ще один рівень: протокол взаємодії між двома системами.

Він може визначати, наприклад:

  • послідовність кроків;
  • обов’язкові можливості сторін;
  • значення певних повідомлень;
  • правила повторних запитів;
  • умови сумісності.

Цей протокол може розвиватися окремо від HTTP API.

Тому я не використовую номер API як автоматичну відповідь на питання, яку версію протоколу підтримує клієнт.

Формат даних теж може мати власну версію

JSON - Версія конкретного формату даних
{  "schemaVersion": 3,  "data": {    "..."  }}

Є ще один тип сумісності: форма даних, які зберігаються, передаються або імпортуються.

Такий формат може мати власну schemaVersion.

Це особливо корисно, якщо одна версія API повинна вміти приймати або читати кілька поколінь певних даних.

Тоді оновлення схеми не змушує мене штучно змінювати версію всього API.

Один номер для всього створює зайву залежність

Штучно зв’язані версії
product 5   |   +--> API v5   +--> protocol v5   +--> schema v5 Any change   |   veverything must move together
Незалежні версії
product 5.2.0 API v2 protocol v3 schema v6 Each number changesonly when its own contract changes.

Якщо всі версії примусово мають однаковий номер, будь-яка зміна починає тягнути за собою інші.

Оновилася внутрішня версія продукту - здається, що потрібно підняти API. Змінилася схема одного документа - номер протоколу теж ніби має змінитися.

Це створює зв’язок там, де його насправді немає.

Незалежне версіювання дозволяє змінювати тільки той контракт, який справді змінився.

Новий deploy не означає нову версію API

Ще одна межа, яку я намагаюся не змішувати, - deploy і версія контракту.

Система може розгортатися десятки разів, поки зовнішній API залишається тієї самої версії.

Це нормально.

Нова версія API потрібна не через сам факт нового release, а коли змінюється зовнішня домовленість так, що старий клієнт більше не може безпечно працювати за попередніми правилами.

Коли я думаю про нову основну версію API

Для мене питання про нову версію API починається не з номера release, а з сумісності.

Я дивлюся, чи змінюється задокументований зовнішній контракт:

  • обов’язкове поле запиту;
  • форма відповіді;
  • значення вже існуючого поля;
  • поведінка операції;
  • семантика статусу або помилки;
  • правило, на яке зовнішній клієнт має право покладатися.

Якщо зміна зворотно сумісна, нова основна версія може взагалі не знадобитися.

Кожна версія повинна відповідати на одне чітке питання

Різні версії - різні питання
Версія застосунку    Який випуск програмного забезпечення працює? Версія API    На який зовнішній контракт покладається клієнт? Версія протоколу    За якими правилами взаємодіють сторони? Версія схеми    За якою структурою потрібно читати ці дані?

Ця перевірка допомагає мені помітити неправильне змішування версій.

Якщо я не можу коротко пояснити, що саме означає певний номер, швидше за все, межа версіювання визначена нечітко.

А якщо для відповіді на два різні питання я використовую одне й те саме число, варто перевірити, чи не зв’язала я випадково незалежні контракти.

Клієнту не обов’язково знати версію всього продукту

Зовнішньому клієнту зазвичай не потрібно знати номер кожного внутрішнього release.

Йому важливо знати те, що впливає на сумісність саме його інтеграції.

Якщо клієнт працює з API v2 і цей контракт залишається сумісним, внутрішній продукт може пройти через багато наступних випусків без будь-якої зміни з боку клієнта.

Це одна з причин, чому стабільний зовнішній контракт варто відділяти від темпу внутрішньої розробки.

Що я перевіряю перед додаванням нової версії

Перед тим як додати ще один номер версії, я ставлю кілька питань:

  • Що саме версіонується?
  • Яку сумісність цей номер захищає?
  • Хто повинен знати цю версію?
  • Чи може вона змінитися незалежно від версії застосунку?
  • Чи не використовую я вже іншу версію для зовсім іншого контракту?
  • Чи справді поточна зміна несумісна, чи це просто новий release?

Ці питання часто дозволяють уникнути версії, яка насправді нічого чітко не означає.

Версії потрібні для керування сумісністю, а не для однакових номерів

Для мене головний принцип тут дуже простий: я не намагаюся синхронізувати номери, які описують різні речі.

Продукт може отримати новий release без зміни API.

Протокол може розвиватися незалежно від версії застосунку.

Окрема структура даних може мати власну версію схеми.

І поки зовнішній API залишається сумісним зі своїм задокументованим контрактом, його основна версія не повинна змінюватися лише тому, що всередині системи відбувся черговий реліз.

Хороше версіювання для мене починається не з вибору числа, а з чіткого розуміння межі сумісності.

Одна система може мати кілька правильних номерів версій одночасно, якщо кожен із них описує свою межу сумісності.