How can I get the grpc gateway rest request response in protobuf?

1.2k Views Asked by At

I am using gRPC gateway for the backward compatibility support but I encountered an issue where in our REST APIs we are using the Protobuf with REST. But in gRPC gateway we are using JSON as a response type. Now when we have migrated towards gRPC, but I am not seeing any option where I will receive the response as a proto type not the JSON type. Can someone please help me in this?

I am getting content-type with the REST url: application/json What I need: application/x-protobuf

EDIT: I have this service contract

service TestService {
  rpc GetBattleStatusByEntityIds(ProtoRequest) returns (ProtoResponse) {
    option (google.api.http) = {
      get : "/test"
    };
  }
}

When I am hitting this /test url then I am receiving the response with content type application/json but I need the data in application/x-protobuf format. I checked the grpc-gateway code and it is using a marshaller which change the response from protobuf to json. Can you please help me to keep it like json any code sample would help.

https://github.com/grpc-ecosystem/grpc-gateway/blob/main/runtime/marshal_jsonpb.go

Picture of wanted response type: https://i.stack.imgur.com/jvR3w.png

2

There are 2 best solutions below

2
nj_ On

You need to add an Accept header - which grpc-gateway will then use when deciding how to render the response.

In the most simple sense, Content-Type indicates to the server what type of content the request body is, whilst Accept tells the server what type of content you're willing to accept in the response body.

So in your case, you'll want to use Accept: application/x-protobuf

$ curl -s -X POST --header 'Accept: application/x-protobuf' localhost:8081/test | hexdump -C
00000000  0a 04 08 0a 10 03                                 |......|

Continue to set the Content-Type header if you're sending content too.

0
MOHAMMAD ARSHAD On

Finally got the answer while initialising the NewServeMux, I need to add my custom marshaler. Gateway have already proto marshaler which saves my efforts.

gatewayMux := runtime.NewServeMux(
        runtime.WithMarshalerOption("application/protobuf", &runtime.ProtoMarshaller{}),
    )