Могу ли я удалить требуемое поле protobuf?
У меня есть клиент-серверное приложение, где сервер передает сериализованные объекты в формате protobuf клиенту, и я хотел бы уйти в отставку в поле required
. К сожалению, я не могу одновременно изменять клиент и сервер, чтобы использовать новое определение .proto
.
Если я изменяю поле required
как optional
, но только для кода, который сериализует сообщения (т.е. десериализационный код не был перестроен и все еще считает его полем required
), могу ли я продолжать публиковать сообщения, может быть десериализовано , пока я заполняю значение для поля now- optional
?
(Похоже, это так, по крайней мере, для нескольких тривиальных случаев, с которыми я экспериментировал (только с использованием Java), но мне интересно, если это вообще разумный подход, и есть ли какие-либо краевые случаи и т.д. я должен беспокоиться).
Мотивация. Моя цель - удалить поле required
в клиент-серверном приложении, где сервер публикует сообщения, которые десериализуются клиентом. Мой предполагаемый подход:
- Измените
required
на optional
на соединительной линии.
- Если необходимо развернуть новый код сервера (для несвязанных функций/исправлений), убедитесь, что в сообщении добавлено дополнительное поле.
- Постепенно разворачивайте обновленный код для всех клиентов (это потребует времени, поскольку оно требует участия других команд со своими расписаниями выпуска).
- Подтвердите, что все клиенты обновлены.
- Начните убирать (то есть не заполнять) необязательное поле.
Ответы
Ответ 1
В соответствии с документацией формата кодирования, требуется ли поле или нет, оно не закодировано в сериализованном потоке байтов. То есть optional
или required
не имеет никакого значения в кодированном сериализованном сообщении.
Я подтвердил это на практике, используя код, сгенерированный Java, путем записи сериализованных сообщений на диск и сравнения вывода - с помощью сообщения, содержащего все поддерживаемые примитивные типы, а также поля, представляющие другие типы.
Ответ 2
Пока установлено поле, использование метода parseFrom(byte[])
для десериализации будет по-прежнему работать, потому что байт [] будет таким же.
Однако можно было бы задаться вопросом, почему вы изменили бы поле из обязательного на факультативное, пока не будете готовы разрешить ему быть необязательным? В основном вы просто делаете его "необязательным" в файле .proto, но вы обеспечиваете его необходимость, всегда заполняя его. Просто мысль.