在 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 中接收数组的主要内容,如果未能解决你的问题,请参考以下文章

如何在 protobuf 消息中建模 Java 原始 int[] 数组

RPC规范中结构内的二维数组定义不起作用

从服务器向客户端发送带有 sun rpc 的结构数组

0513JS数组的定义遍历添加

5.13js 数组

数组内的jquery模板数组