流程如下:
>客户端向API发送JSON请求.
> API将JSON数据转换为protobuf结构,然后将其发送到负责处理它的微服务.
>微服务从API接收数据并对其执行任何操作,在这种情况下,我正在尝试更改MySQL表中的单个值,例如客户端的电子邮件地址.
现在,我遇到的问题是,由于protobuf(可以理解)不允许指针,protobuf对象将包含未提供的所有内容的零值.这意味着如果客户想要更新他们的电子邮件地址,我不知道他们是否也将IncludeInMailLists设置为false – 或者如果它只是没有提供(具有零值)并且不应该更改.
问题是:我如何 – 从protobuf对象 – 知道一个值是否被明确地设置为0,或者只是没有提供?
我当前的解决方案几乎有一个特殊的UpdateCustomer-object,它还有一个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)以来,未设置的基元和已设置为“零值”的基元(假,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 {}
请注意导入“google / protobuf / wrappers.proto”;很重要
它允许您访问google protobufs包装器source code here.这些不是具有允许您测试存在的方法的对象.
在java中生成的Grpc代码为您提供了诸如.hasEmail()之类的方法,如果该值存在,则返回true.未设置值的getter仍然会返回零值.我认为golang版本使用的指针可以测试nil而不是显式的hasX()方法.
更多信息/讨论在github issue