我正在构建一个包含多个断开连接的组件的微服务系统,目前我正在尝试了解如何根据提供的 protobuf
数据了解对象上的哪些字段应该更新。
流程是这样的:
- 客户端向 API 发送 JSON 请求。
- API 将 JSON 数据转换为
protobuf
结构,然后将其发送到负责处理它的微服务。 - 微服务从 API 接收数据并对其执行任何操作,在本例中,我尝试更改 MySQL 表中的单个值,例如客户的电子邮件地址。
现在,我遇到的问题是,由于 protobuf
(可以理解)不允许指针,protobuf
对象将包含所有未提供的零值。这意味着如果客户想要更新他们的电子邮件地址,我不知道他们是否也将 IncludeInMailLists
设置为 false
- 或者如果它根本没有提供(有它的零值)并且不应更改。
问题是:我如何从 protobuf 对象知道一个值是明确设置为 0,还是只是没有提供?
我目前的解决方案几乎是有一个特殊的 UpdateCustomer
对象,它还有一个 Fields
数组,指定微服务应该关心哪些字段,但感觉很糟糕解决方案。
一定有人已经更好地解决了这个问题。我该如何实现?
最佳答案
Protobufs 字段掩码是一种方式。
https://github.com/golang/protobuf/issues/225
但是如果你使用 grpc然后有一种(某种)内置方式。
Grpc 包装器
自 proto3(protobufs v3)以来,未设置的基元与设置为“零值”(false、0、""等)的基元之间没有区别。
相反,您可以使用对象或 protobufs 语言中的“消息”,因为对象可以是 nil/null。您没有提到您使用的是哪种语言,但希望这些示例有意义。
给定一个 RPC 服务,例如:
import "google/protobuf/wrappers.proto";
service Users {
rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse)
}
message UpdateUserRequest {
int32 user_id = 1;
google.protobuf.StringValue email = 2;
}
message UpdateUserResponse {}
注意 import "google/protobuf/wrappers.proto";
很重要。
它使您可以访问 google protobufs 包装器 source code here .这些不是具有允许您测试存在性的方法的对象。
Java 中的 Grpc 生成代码为您提供了诸如 .hasEmail()
之类的方法,如果值存在,它会返回 true
。未设置值上的 getter 仍将返回零值。我认为 golang 版本使用可以测试 nil 的指针,而不是显式的 hasX()
方法。
更多信息/讨论在此 github issue
关于go - 从 protobuf 更新数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46060765/