ts 使用 grpc ts-proto 的一点问题

157 天前
 byqtxdy07

我在 proto 文件中定义了一个 message

message ArticleUpdateReq {
  optional string title = 3;
}

当我通过 ts-proto 生成的代码作为客户端发送请求时发现:即使我客户端不传递 title 字段,在服务端接收数据的时候 title 也会有一个空字符串的默认值 "",这导致了我无法判断用户是删除了 title ,还是没有修改 title(用的 java mp ,原本是传的 null 的话就视为没有修改,传 "" 就视为删除)

我查阅了下资料,说可以写成

message ArticleUpdateReq {
  optional google.protobuf.StringValue title = 3;
}

我看了一下生成的 java 服务端生成的代码,雀氏没有默认值""了,但又出现了一个新的问题:

ts-proto 生成新的代码并发送请求报错了:

Request message serialization failure: .article.ArticleUpdateReq.title: object expected

求大佬们帮小弟看看这两个问题😙😙😙

943 次点击
所在节点    程序员
11 条回复
sujin190
157 天前
生成的结构还有个 hasTitle 的属性吧,你看看,客户端不给 title 赋值的时候服务端接收解码这个属性返回的就是 false ,null 值不标准,需要额外信息传递不说可能有的语言无法正确处理 null 语义
XCFOX
157 天前
只能说 TypeScript 领先太多了。grpc 是带着 C/C++、Go 的包袱设计的。在 Go 中不传值就是零值,根本没办法区分 undefined 和空字符串。
能用 json 还是用 json 吧,根本不差 protobuf 那点性能。如果是服务间通讯的话试试 nats 消息中间件,实测延迟比 grpc 低,速度比 grpc 快。
byqtxdy07
157 天前
@sujin190 !我看了一眼,直接生成的 ts 代码和 java 代码都没有显式的 hasTitle 属性,java 这边 request 请求体中倒是有一个 hasField 的 api
byqtxdy07
157 天前
@XCFOX 不行的话雀氏要转回 json 了😂
byqtxdy07
157 天前
@sujin190 试了一下,好像 proto2 中是有这个 hasTitle 的设置的,但 proto3 就没有了,不知道按下面这样写能不能用:
request.hasField(ArticleProto.ArticleCreateReq.getDescriptor().findFieldByName("title"));
但不是很方便,硬编码是一方面,再加一个属性多的话写起来也有点麻烦
AloneHero
157 天前
Proto2 默认值应该是挂载在原型链上的,如果是主动传递的值则在实例上。不知道 proto3 改变没有,应该没改
sujin190
157 天前
@byqtxdy07 #5 我们用的也是 proto3 啊,optional 标记的字段就有 has 相关属性。。你这啥毛病

https://protobuf.dev/programming-guides/field_presence/

你看这个文档,按文档中的意思,V2 版本并不需要标记为 optional 就有 has 方法,V3 只有标记为 optional 的才有 has 方法,这好像和有些搜索结果说的不一样啊
sujin190
157 天前
How to Enable Explicit Presence in Proto3
These are the general steps to use field tracking support for proto3:

Add an optional field to a .proto file.
Run protoc (at least v3.15, or v3.12 using --experimental_allow_proto3_optional flag).
Use the generated “hazzer” methods and “clear” methods in application code, instead of comparing or setting default values

@byqtxdy07 #5 好吧,你看后面一段,这个规则需要在 3.15 版本以上才有,3.12 以上需要用 --experimental_allow_proto3_optional 来开启,其它版本应该就是搜索的结果一样不支持,我们用的 3.17 所以正常了,需要的话升级以下呗,grpc 应该兼容新版本的 protobuf 的吧
byqtxdy07
157 天前
@sujin190 ok ,谢谢大佬,我晚点试试
byqtxdy07
156 天前
@sujin190 解决了解决了,谢谢大佬 😙😙😙
Aoang
156 天前
buf.build + connectrpc 省事很多

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1011830

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX