grpc-ecosystem / grpc-gateway

gRPC to JSON proxy generator following the gRPC HTTP spec

Home Page:https://grpc-ecosystem.github.io/grpc-gateway/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Grpc Gateway discards Any typed fields

ginwakeup opened this issue · comments

🐛 Bug Report

We have a Service that takes in a request with an Any type field, e.g.

message Request {
      string normalField = 1;
      google.protobuf.Any anyField = 2;
}

message MyType {
    string name = 1;
}

 ```

When making a request to our gateway service using python and requests, the `anyField` data is totally discarded by the Gateway, ending up with an empty field which actually should contain data:

```python
import requests

apiUrl = "http://localhost:80/my-service"
payload = {
    "normalField": "normalData",
    "anyField": {
        "name": "my-name"
    }
}

result = requests.put(apiUrl, json=payload, verify=False)
print(result)

On the gRPC Server, the content of the request is the following:

normalField: "normalData"
anyField {}

As you can see the field anyField is empty while it should be parsed to MyType and its field name should contain the value my-name.

A question that might arise is how does the grpc-gateway know what type to convert the Any type? I guess this is an implementation detail.

To Reproduce

  1. Create messages as specified in the example
  2. One of the messages has to contain an Any type
  3. Write a python script to create a REST http request to the grpc gateway and make sure you fill the details for the Any field as well
  4. Check on the server side, the Any field is empty.

Expected behavior

The Any field should be parsed correctly to whatever type it needs to be parsed to.
I guess to achieve this we probably need to pass the type_url so the Gateway knows what type to Unpack to.

Actual Behavior

The Any field content is totally discarded, ending up in discarded fields.

Your Environment

go 1.21

require (
	github.com/golang/glog v1.1.2
	github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1
	google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect
	google.golang.org/grpc v1.60.0
	google.golang.org/protobuf v1.31.0
)

require (
	google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17
	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0
)

Hi, thanks for your issue. Unfortunately, this seems to stem from a misunderstanding of what the google.protobuf.Any type can do when using JSON. The JSON representation of the any type can be found here: https://pkg.go.dev/google.golang.org/protobuf/types/known/anypb#Any.

What you probably want to use here is a google.protobuf.Struct type, which can describe arbitrary JSON inputs. While this will help with your example, I would still recommend against using generic types like this. Using strong types is the way to go with Protobuf, it'll help avoid issues like this.

I'm going to close this as this isn't a problem with the grpc-gateway. Let me know if you need further assistance.

@johanbrandhorst Adding the type in the metadata helped and now it's working. Thank you!!