在 Proto RPC 中接收数组
Posted
技术标签:
【中文标题】在 Proto RPC 中接收数组【英文标题】:Receive Array in Proto RPC 【发布时间】:2021-06-16 19:19:06 【问题描述】:我使用 rpc 构建了一个由 proto 文件生成的 REST 服务。 我成功接收到一个事件如下:
rpc PostEvent(Event) returns (google.protobuf.Empty)
option (google.api.http) =
post: "/myEP"
body: "*"
;
它可以工作 - 将 json 对象转换为 Event 结构。
我的问题是,当我想接收 Event 数组时如何做同样的事情。
这可以工作:
message EventsWrapper
repeated Event events = 1;
rpc PostEvents(EventsWrapper) returns (google.protobuf.Empty)
option (google.api.http) =
post: "/myEP"
body: "*"
;
但是它会期望一个像这样的json:
"事件":[,..,]
虽然我只收到:
[,..,]
我无法控制接听电话的方式。有什么想法可以调整我的代码来处理这样的数组调用吗?
【问题讨论】:
根据protobuf标准,gRPC服务只能将消息类型作为参数,消息类型只能表示为JSON对象。因此,至少按照规范,您不能使用 PB 来定义直接采用 JSON 数组的服务。 【参考方案1】:如果你需要接受一个 JSON 数组,并且你使用的 gRPC 转码实现支持它,你可以使用body
属性来指定映射到请求正文的重复字段,而不是使用*
。
引用Google HttpRule API documentation:
如果 API 需要为请求或响应正文使用 JSON 数组,它可以将请求或响应正文映射到重复字段。但是,某些 gRPC 转码实现可能不支持此功能。
body
— 请求字段的名称,其值映射到 HTTP 请求正文,或 * 用于将路径模式未捕获的所有请求字段映射到 HTTP 正文,或因没有任何 HTTP 请求正文而省略.
换句话说,您可以将您的服务定义为:
message EventsWrapper
repeated Event events = 1;
// ...
rpc PostEvents(EventsWrapper) returns (google.protobuf.Empty)
option (google.api.http) =
post: "/myEP"
body: "events"
;
我相信至少gRPC-Gateway(自PR #712)和Envoy Proxy 的gRPC-JSON transcoder 都支持这一点。后者还支持在 JSON 数组和流式 gRPC 方法之间进行转换,因此如果您定义 rpc PostEvent(stream Event) returns (google.protobuf.Empty)
方法,Envoy 将期望请求中有一个 Event
对象数组(甚至可能在翻译消息到达时对其进行流式传输)。
【讨论】:
以上是关于在 Proto RPC 中接收数组的主要内容,如果未能解决你的问题,请参考以下文章