为什么在 Protocol Buffers 3 中移除了 required 和 optional

Why required and optional is removed in Protocol Buffers 3

我最近将 gRPCproto3 一起使用,我注意到 requiredoptional 已在新语法中删除。

谁能解释一下为什么 required/optional 在 proto3 中被删除了?这种约束似乎是使定义稳健的必要条件。

语法原型 2:

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

语法原型 3:

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

required 的实用性一直是许多争论和争论的焦点 war。双方都有大型营地。一个阵营喜欢保证一个值存在并且愿意忍受它的局限性,但另一个阵营认为 required 危险或无益,因为它不能安全地添加或删除。

让我解释一下为什么 required 字段应该谨慎使用的原因。如果您已经在使用原型,则无法添加必填字段,因为旧应用程序不会提供该字段,而且应用程序通常无法很好地处理故障。您可以确保首先升级所有旧应用程序,但很容易出错,如果您将原型存储在 any 数据存储中(即使是短-住,就像 memcached)。删除必填字段时也会出现同样的情况。

许多必填字段 "obviously" 是必填字段,直到……它们不再是必填字段。假设您有一个 id 字段用于 Get 方法。这显然是 所必需的。除非,稍后您可能需要将 id 从 int 更改为 string,或将 int32 更改为 int64。这需要添加一个新的 muchBetterId 字段,现在您只剩下 必须 指定的旧 id 字段,但最终会被完全忽略。

当这两个问题结合在一起时,有益的 required 领域的数量变得有限,阵营争论它是否仍然有价值。 required 的反对者不一定反对这个想法,但反对它目前的形式。一些人建议开发一个更具表现力的验证库,可以检查 required 以及更高级的东西,如 name.length > 10,同时确保有一个更好的故障模型。

Proto3 总体上似乎更倾向于简单,required 删除更简单。但也许更有说服力,删除 required 与其他功能结合使用时对 proto3 有意义,例如删除基元的字段存在和删除覆盖默认值。

我不是 protobuf 开发人员,在这个问题上我绝不是权威,但我仍然希望解释对您有用。

您可以在protobuf Github issue中找到解释:

We dropped required fields in proto3 because required fields are generally considered harmful and violating protobuf's compatibility semantics. The whole idea of using protobuf is that it allows you to add/remove fields from your protocol definition while still being fully forward/backward compatible with newer/older binaries. Required fields break this though. You can never safely add a required field to a .proto definition, nor can you safely remove an existing required field because both of these actions break wire compatibility. For example, if you add a required field to a .proto definition, binaries built with the new definition won't be able to parse data serialized using the old definition because the required field is not present in old data. In a complex system where .proto definitions are shared widely across many different components of the system, adding/removing required fields could easily bring down multiple parts of the system. We have seen production issues caused by this multiple times and it's pretty much banned everywhere inside Google for anyone to add/remove required fields. For this reason we completely removed required fields in proto3.

After the removal of "required", "optional" is just redundant so we removed "optional" as well.

protobuf 3.15 中返回了可选字段