Каковы принципы обеспечения обратной и прямой совместимости в gRPC?

Ответ

Обратная и прямая совместимость в gRPC достигается за счет правил эволюции схемы в Protocol Buffers (Protobuf), который используется для сериализации данных.

Основные правила для неломающих изменений:

  1. Не изменять и не переиспользовать теги существующих полей. Тег (числовой идентификатор) — это ключ к данным в бинарном формате. Его изменение сломает парсинг у старых клиентов/серверов.

  2. Добавление новых полей. Новые поля можно безопасно добавлять. Старые клиенты просто проигнорируют их при десериализации. Новые клиенты смогут с ними работать.

  3. Удаление полей. Поля нельзя просто удалять из .proto файла. Вместо этого их следует помечать как reserved. Это предотвращает случайное переиспользование тега в будущем, что могло бы привести к ошибкам.

    message MyMessage {
      reserved 2, 15, 9 to 11;
      reserved "old_field_name";
    }
  4. Переименование полей. Переименование поля безопасно, так как Protobuf идентифицирует поля по их числовому тегу, а не по имени.

Пример совместимого изменения (добавление поля):

Версия 1:

message User {
  string id = 1;
  string name = 2;
}

Версия 2:

message User {
  string id = 1;
  string name = 2;
  // Новое опциональное поле
  optional string email = 3; 
}

Сервер, использующий Версию 2, может отправить User с полем email. Клиент с Версией 1 получит это сообщение, успешно распарсит поля id и name, а поле email просто проигнорирует.

Ломающие изменения (требуют новой версии API):

  • Изменение типа данных существующего поля.
  • Изменение номера тега существующего поля.
  • Удаление обязательного (required) поля (в proto2).