Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як змінювати схему Protocol Buffers, не ламаючи сумісність клієнтів і серверів?

У Protocol Buffers у повідомленні передаються не назви полів, а їхні номери. Звідси головні правила еволюції схеми: важливо не те, як поле називається, а який у нього номер і тип.

Безпечні зміни:

  • додати нове поле з новим номером. Старі клієнти його проігнорують, нові - отримають значення за замовчуванням, якщо старий сервер його не надіслав;
  • перейменувати поле - номер той самий, на «дроті» нічого не змінилося (але згенерований код зміниться - це зміна API для коду, не для формату);
  • видалити поле, якщо його номер і назву зарезервувати.

Небезпечні зміни:

  • змінити номер поля - для формату це видалення старого поля і поява нового;
  • повторно використати номер видаленого поля з іншим змістом - старі клієнти розберуть нові дані як старе поле, з тихим пошкодженням даних;
  • змінити тип на несумісний (string → int64). Деякі пари сумісні на рівні формату (int32/int64/bool), але з можливим обрізанням значень - покладатися на це не варто;
  • перетворити одиничне поле на repeated чи навпаки - з неочевидними наслідками для різних мов.

Резервування видалених полів:

message Invoice {
  reserved 3, 7;
  reserved "discount", "legacy_status";

  int64 id = 1;
  string number = 2;
  int64 total_cents = 4;
}

Компілятор не дасть використати зарезервовані номери й назви повторно.

Інші практики:

  • значення за замовчуванням у proto3 - 0, "", false неможливо відрізнити від «не задано». Якщо різниця важлива - optional (явна присутність) чи обгорткові типи;
  • перелічення: перше значення має бути 0 і означати «невідомо» (STATUS_UNSPECIFIED = 0), бо саме його отримає старий клієнт для нових значень;
  • версія в назві пакета (billing.v1, billing.v2) - для справді несумісних змін створюється новий пакет і обидва обслуговуються паралельно;
  • автоматична перевірка в CI: інструмент buf breaking порівнює схему з попередньою версією й знаходить ламаючі зміни до злиття.

Порядок розгортання: спершу оновлюються ті, хто читає нове поле (сервери, що його приймають), потім ті, хто починає його надсилати. Видалення - у зворотному порядку: спершу всі припиняють використовувати поле, потім воно резервується.

Докладніше в документації: Protocol Buffers: оновлення типу повідомлення

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання