2

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

  • 1
    [Provide a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – Mattia Righetti Mar 23 '23 at 10:44
  • hey, updated the question. Please revisit. – MOHAMMAD ARSHAD Mar 23 '23 at 11:42
  • I've **not** tried this. Envoy documents [sending arbitrary content](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/grpc_json_transcoder_filter#sending-arbitrary-content) using Google's (!) [`google.api.HttpBody`](https://github.com/googleapis/googleapis/blob/master/google/api/httpbody.proto). I **assume** that this mechanism is supported by gRPC Gateway too. – DazWilkin Mar 23 '23 at 16:22

2 Answers2

0

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.

nj_
  • 2,219
  • 1
  • 10
  • 12
  • It's not working in grpc-gateway, content-type is still application/json – MOHAMMAD ARSHAD Mar 25 '23 at 03:48
  • You need to share some code then, as it works perfectly well for me. This is how I've set it up on my side: https://gist.github.com/nick-jones/f404ae94b38d4c701f8d539cac5c1ae0 – nj_ Mar 25 '23 at 08:08
0

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{}),
    )