You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何定义Protobuf以返回无键重复对象的JSON数组?

Protobuf返回顶层JSON数组的解决方案

针对你需要保持遗留API契约(返回顶层JSON数组)的需求,有两种可行方案:

方案1:通过gRPC-Gateway的HTTP注解适配

如果你使用gRPC-Gateway将gRPC服务转为REST API,可以通过google.api.http注解指定将重复字段直接作为响应体返回,无需额外的外层键:

import "google/api/annotations.proto";
import "google/protobuf/empty.proto";

message Example {
  string name = 1;
  string value = 2;
}

message Response {
  repeated Example example = 1;
}

service ExampleService {
  rpc GetExamples(google.protobuf.Empty) returns (Response) {
    option (google.api.http) = {
      get: "/v1/examples"
      response_body: "example" // 将response中的example字段作为响应体直接返回
    };
  }
}

这样生成的REST接口会直接输出[{"name": "the name", "value": "the value"}, ...]格式的JSON,完全匹配遗留API的契约。

方案2:使用RPC流返回(你提到的方案)

定义rpc Example(google.protobuf.Empty) returns (stream Example)是可行的,但需要注意场景:

  • 若通过gRPC-Gateway转REST,网关会自动将流中的多个Example消息拼接成一个JSON数组返回,符合需求。
  • 若前端直接调用gRPC服务(如gRPC-Web),流返回会让前端收到多个独立的对象,而非数组,此时需要前端额外拼接,反而会破坏契约,这种情况不建议用此方案。

如果不需要流式传输的特性(如分批返回数据),用流返回只是为了适配JSON格式,虽然语义上略有不严谨,但实际使用中是可以接受的。

额外说明

  • 纯Protobuf转JSON的工具(如protoc --json_out)默认不支持顶层数组,因此必须通过网关或自定义序列化逻辑处理。
  • 使用google.api.http注解需要引入对应的proto文件,并确保代码生成时包含相关插件。

内容的提问来源于stack exchange,提问作者Kyle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:56:06