Например, если я изменился с:
message Request {
int foo = 1;
}
к
message Request {
int bar = 1;
int foo = 2;
}
Безопасно ли менять foo
с 1 на 2? Документы запрещают: These numbers are used to identify your fields in the message binary format, and should not be changed once your message type is in use.
, но хотелось бы знать, почему.
Отвечает ли это на ваш вопрос? Могу ли я изменить пронумерованные теги в файле proto?
Если у вас есть сериализованная версия сообщения, созданная с помощью первой версии, вы не сможете десериализовать вторую версию сообщения. Если вы используете protobuf для создания модели для хранения в БД или для публикации в брокере, таком как Apache Kafka, вам необходимо следовать соглашению. Если вы используете протобуфер для создания модели и сервиса для онлайн-использования, вы не должны ничего ломать (если вы будете перегенерировать все модели)
См. также зарезервированное ключевое слово , чтобы не использовать повторно старый номер. Дальнейшее чтение также здесь
Допустим, у меня есть библиотека A, владеющая прототипами, и библиотека B, использующая прототипы, такие как myRequest.foo
. Если я изменю номер поля foo
в библиотеке A, сломается ли библиотека B, если попытается обработать новый прототип со старым кодом?
@onepiece не должен сломаться (что означает: вызвать ошибку), если только старый код не знал о каком-то другом поле 2 с другим типом (поэтому удаление полей опасно, если вы не помечаете их как зарезервированные). Однако новая сериализация использует поле 1 для bar и 2 для foo; Таким образом, старый код сериализатора десериализует то, что было значениями бара, в поле с именем foo, а то, что было значением foo, будет потеряно (или сохранено в труднодоступном API как данные неизвестного поля). На проводе сохраняется только номер поля (не имя). По сути, не меняйте номера полей. Почти никогда.
@MarcGravell Можно ли изменить номера полей, если, скажем, прототип принадлежит и используется только в библиотеке A? Затем все варианты использования прототипа будут обновлены вместе. Я также видел stackoverflow.com/a/26826460/1661745 - if you change the numbering scheme, and apply this change to both serializer and deserializer, there is no issue.
@onepiece, который зависит: у вас есть полезные данные, хранящиеся в файлах? В базах данных? В очередях сообщений? Если ответ на любой из этих (и других) вопросов «возможно», то нет, это не нормально. Откровенно говоря, меняя номер поля, вы абсолютно ничего не выигрываете, а рискуете очень сильно. Для меня это много слов и потраченного впустую времени, которое можно сэкономить, просто оставив поле в покое. Никто не будет возражать.
Мы следуем этому соглашению и для онлайн-сервиса и используем зарезервированные ключевые слова каждый раз (два раза за три года), когда поле удаляется из сообщения.