Search code examples
jsonprotocol-buffersprotobuf-go

Protobuf to json array with no key for repeated objects


I'm working on converting a legacy existing API that is actively being consumed to utilize Protobuf and in a new service. The goal is to move the API without breaking our FE's, which means the contracts need to stay identical. The current JSON returned by the legacy API looks as follows:

[
    {
        "name": "the name",
        "value": "the value"
    },
    {
        "name": "the name2",
        "value": "the value2"
    }
]

Typically I use repeated messages to handle returning a list of objects through protobuf. However, this requires a key to be added to the JSON array which breaks the FE's contract.

Example:

message Response {
  repeated Example example = 1;
}

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

This results in JSON which looks like the below and breaks the contract.

{
    "example": [
        {
            "name": "the name",
            "value": "the value"
        },
        {
            "name": "the name2",
            "value": "the value2"
        }
    ]
}

Is there a way to defined the protobuf messages to return a repeated list without providing it a message key? I've seen that there is also the concept of returning a stream of objects through the RPC definition. I'm wondering is that the proper way to handle this situation even though I'm not really utilizing the stream potential? But instead return:

rpc Example(google.protobuf.Empty) returns (stream Example)

Thanks


Solution

  • Ok I found my answer after digging through some old issues in GRPC-Gateway Github. This issue called out a similar situation to mine. Once it was added it pointed to the correct spot in the documentation: https://github.com/grpc-ecosystem/grpc-gateway/issues/707

    https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#httprule

    Under special notes https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.api#special-notes I found the field for responseBody

    In my RPC definition, I was able to add a responseBody field which pulls out my array to the top level JSON:

    option (google.api.http) = {
          get: "/test/v1/test"
          response_body: "example"
        };
    

    This then left me with the JSON I needed.