Почему требуется и необязательно удаляется в буферах протоколов 3

Недавно я использовал gRPC с proto3, и я заметил, что required и optional были удалены в новом синтаксисе.

Кто-нибудь объяснит, почему требуемые/необязательные удаляются в proto3? Подобные ограничения просто кажутся необходимыми, чтобы сделать определение надежным.

синтаксис proto2:

message SearchRequest {
  required string query = 1;
  optional int32 page_number = 2;
  optional int32 result_per_page = 3;
}

синтаксис proto3:

syntax = "proto3";
message SearchRequest {
  string query = 1;
  int32 page_number = 2;
  int32 result_per_page = 3;
}

Ответ 1

Полезность required лежит в основе многих дискуссий и пламенной войны. Большие лагеря существовали с обеих сторон. Один лагерь любил гарантировать, что ценность присутствует и была готова жить с ее ограничениями, но в другом лагере чувствовала себя required опасной или бесполезной, поскольку ее нельзя безопасно добавить или удалить.

Позвольте мне объяснить больше причин, почему поля required следует использовать экономно. Если вы уже используете протокол, вы не можете добавить требуемое поле, потому что старое приложение не будет предоставлять это поле, а приложения в целом не справятся с отказом. Вы можете убедиться, что все старые приложения сначала обновлены, но может быть легко сделать ошибку, и это не поможет, если вы храните протосы в любом хранилище данных (даже недолго, например memcached). Такая же ситуация применяется при удалении обязательного поля.

Многие обязательные поля были "явно" необходимы, пока... они не были. Скажем, у вас есть поле id для метода Get. Это, очевидно, требуется. Кроме того, позже вам может потребоваться изменить id от int до строки или int32 до int64. Для этого требуется добавить новое поле muchBetterId, и теперь вы остаетесь со старым полем id, которое должно быть указано, но в конечном итоге полностью игнорируется.

Когда эти две проблемы объединены, количество полезных полей required становится ограниченным, и лагеря спорят о том, имеет ли он все еще значение. Противники required не обязательно были против идеи, а ее нынешней формы. Некоторые предложили создать более выразительную библиотеку проверки, которая могла бы проверить required вместе с чем-то более продвинутым, например name.length > 10, а также убедиться, что у него лучшая модель отказа.

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

Я не разработчик протобуфа и никоим образом не авторитетен по этому вопросу, но я все еще надеюсь, что объяснение будет полезно.