go - 从 protobuf 更新数据

标签 go protocol-buffers

我正在构建一个包含多个断开连接的组件的微服务系统,目前我正在尝试了解如何根据提供的 protobuf 数据了解对象上的哪些字段应该更新。

流程是这样的:

  1. 客户端向 API 发送 JSON 请求。
  2. API 将 JSON 数据转换为 protobuf 结构,然后将其发送到负责处理它的微服务。
  3. 微服务从 API 接收数据并对其执行任何操作,在本例中,我尝试更改 MySQL 表中的单个值,例如客户的电子邮件地址。

现在,我遇到的问题是,由于 protobuf(可以理解)不允许指针,protobuf 对象将包含所有未提供的零值。这意味着如果客户想要更新他们的电子邮件地址,我不知道他们是否也将 IncludeInMailLists 设置为 false - 或者如果它根本没有提供(有它的零值)并且不应更改。

问题是:我如何从 protobuf 对象知道一个值是明确设置为 0,还是只是没有提供?

我目前的解决方案几乎是有一个特殊的 UpdateCustomer 对象,它还有一个 Fields 数组,指定微服务应该关心哪些字段,但感觉很糟糕解决方案。

一定有人已经更好地解决了这个问题。我该如何实现?

最佳答案

Protobufs 字段掩码是一种方式。

https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.FieldMask

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/

相关文章:

go - 性能几乎以线性方式提高,将GOMAXPROCS从1增加到4,但此后保持平稳

java - Windows 上的 Thrift/Google Protocol Buffers

c# - 是否有很好的教程或示例显示 protobuf-net 和 zeromq 的组合?

go - 在 golang 中,如何嵌入自定义类型?

types - 使用类型在 Go 中具有嵌入类型的参数定义函数

google-app-engine - 如何在结构中存储结构?

go - 将结构放入 slice 时出现 golang 错误

go - 在 Go 中查找 gRPC 调用的客户端名称

c# - protobuf.net De-Serializer 无限期等待

go - 如何使用 ProtoBuf 下载文件