protocol-buffers - 为什么 Protocol Buffers 3 中删除了必需和可选

标签 protocol-buffers grpc proto3

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

有人能解释一下为什么在 proto3 中删除了必需/可选吗?这种约束似乎是使定义稳健所必需的。

语法原型(prototype)2:

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

语法原型(prototype)3:

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

最佳答案

required 的实用性一直是许多争论和激烈争论的核心。双方都有大型营地。一个阵营喜欢保证某个值的存在,并且愿意接受其局限性,但另一个阵营则认为 require 是危险的或无用的,因为它无法安全地添加或删除。

让我详细解释一下为什么应谨慎使用 required 字段。如果您已经在使用原型(prototype),则无法添加必填字段,因为旧应用程序不会提供该字段,并且应用程序通常不能很好地处理故障。您可以确保首先升级所有旧应用程序,但是很容易犯错误,并且如果您将原型(prototype)存储在任何数据存储中(甚至是短暂的,例如内存缓存)。删除必填字段时也适用同样的情况。

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

当这两个问题结合在一起时,有益的必填字段的数量就变得有限,并且各阵营争论它是否仍然有值(value)。 required 的反对者并不一定反对这个想法,而是反对它目前的形式。一些人建议开发一个更具表现力的验证库,可以检查required以及name.length > 10等更高级的内容,同时确保拥有更好的故障模型。

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

我不是 protobuf 开发人员,在这个问题上也不具有权威性,但我仍然希望这个解释是有用的。

关于protocol-buffers - 为什么 Protocol Buffers 3 中删除了必需和可选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31801257/

相关文章:

c# - C# 中的 Proto2 与 Proto3

docker - 我尝试在 docker 中部署 gRPC (go) 服务器并在本地端口中公开端口,但端口绑定(bind)不起作用

javascript - 如何通过导入加载 proto 文件

java - Map List<String> with Mapstruct 从 Java POJO 到 Protobuf (proto3)

java - 使用 RProtoBuf( Protocol Buffer )从 R 调用 Java 函数

c++ - Google Protocol Buffers - 缺少必填字段,即使所有字段显然都存在

go - 从客户端向服务器发送大量数据

java - 使用 JMeter TCP Sampler 是否可以使用响应的第一个字节来确定消息长度

在 gRPC 服务前使用 Envoy 代理时出现 SSL 错误 ERR_CERT_AUTHORITY_INVALID