Могу ли я удалить требуемое поле protobuf?

У меня есть клиент-серверное приложение, где сервер передает сериализованные объекты в формате protobuf клиенту, и я хотел бы уйти в отставку в поле required. К сожалению, я не могу одновременно изменять клиент и сервер, чтобы использовать новое определение .proto.

Если я изменяю поле required как optional, но только для кода, который сериализует сообщения (т.е. десериализационный код не был перестроен и все еще считает его полем required), могу ли я продолжать публиковать сообщения, может быть десериализовано , пока я заполняю значение для поля now- optional?

(Похоже, это так, по крайней мере, для нескольких тривиальных случаев, с которыми я экспериментировал (только с использованием Java), но мне интересно, если это вообще разумный подход, и есть ли какие-либо краевые случаи и т.д. я должен беспокоиться).

Мотивация. Моя цель - удалить поле required в клиент-серверном приложении, где сервер публикует сообщения, которые десериализуются клиентом. Мой предполагаемый подход:

  • Измените required на optional на соединительной линии.
  • Если необходимо развернуть новый код сервера (для несвязанных функций/исправлений), убедитесь, что в сообщении добавлено дополнительное поле.
  • Постепенно разворачивайте обновленный код для всех клиентов (это потребует времени, поскольку оно требует участия других команд со своими расписаниями выпуска).
  • Подтвердите, что все клиенты обновлены.
  • Начните убирать (то есть не заполнять) необязательное поле.

Ответ 1

В соответствии с документацией формата кодирования, требуется ли поле или нет, оно не закодировано в сериализованном потоке байтов. То есть optional или required не имеет никакого значения в кодированном сериализованном сообщении.

Я подтвердил это на практике, используя код, сгенерированный Java, путем записи сериализованных сообщений на диск и сравнения вывода - с помощью сообщения, содержащего все поддерживаемые примитивные типы, а также поля, представляющие другие типы.

Ответ 2

Пока установлено поле, использование метода parseFrom(byte[]) для десериализации будет по-прежнему работать, потому что байт [] будет таким же.

Однако можно было бы задаться вопросом, почему вы изменили бы поле из обязательного на факультативное, пока не будете готовы разрешить ему быть необязательным? В основном вы просто делаете его "необязательным" в файле .proto, но вы обеспечиваете его необходимость, всегда заполняя его. Просто мысль.