Контракт живёт дольше одной версии сервиса. Поэтому изменения оценивают по тому, что увидят старые клиенты и старые серверы.
Можно
- добавить новое поле с новым номером;
- добавить новый метод в сервис;
- добавить новое значение enum с осторожной обработкой неизвестного значения;
- игнорировать неизвестные поля на чтении.
Старый клиент пропустит новые поля, старый сервер сохранит их при обычном разборе.
Нельзя
- менять номер существующего поля;
- менять его тип;
- переиспользовать номер удалённого поля;
- переименовывать значение enum.
Удалённые имена и номера резервируют:
reserved 2, 4 to 8;
reserved "legacy_status";
Это защищает от будущего повторного использования.
Незнакомые поля теряются на пути
Сохранение неизвестного поля не гарантирует его доставку. Прокси, преобразование в JSON и обратно или ручная сборка нового сообщения могут молча его выбросить. Поэтому проверяют всю цепочку, а не только клиент и сервер.
buf breaking помогает находить несовместимые изменения до релиза, но не заменяет контрактные тесты со старой и новой версиями.
Две версии в одном rollout
Во время выката старый клиент может говорить с новым сервером, а новый клиент - со старым. Поэтому сначала выпускают сервер, который понимает новые поля, но не требует их. Клиенты начинают слать поля после того, как все серверы обновлены.
Новое поле получает новый номер. Старая версия пропускает его при чтении, поэтому номера удаленных полей резервируют.
Для enum заранее описывают поведение неизвестного значения. switch без default - готовый источник неправильной логики: новый статус нельзя молча принять за старый или выполнить действие по умолчанию.
Контрактный тест сериализует сообщение старой версией, читает новой и проверяет обратный путь. Для критичных полей проверяют ещё и сохранение в базу и Kafka: совместимость protobuf сама по себе не спасает от потери данных при преобразовании.
Коротко
- Добавлять поля и методы безопасно, менять номера и типы нельзя.
- Удалённые имена и номера резервируют.
- Неизвестные поля теряются на преобразователях, не только на старых клиентах.
- Совместимость проверяют автоматически и на двух версиях.