Description
🐛 Bug Report
grpc gateway supports field mask generation. When the item being used to generate the field mask contains a google.protobuf.Struct with populated values grpc gateway returns a 400.
To Reproduce
With the following service definition:
service TestService {
rpc PatchTest (PatchTestRequest) returns (PatchTestResponse) {
option (google.api.http) = {
patch: "/test"
body: "item"
};
}
}
message Item {
string foo = 1;
google.protobuf.Struct struct = 2;
}
message PatchTestRequest {
Item item = 1;
google.protobuf.FieldMask update_mask = 2;
}
message PatchTestResponse {}
Run the following test.
func TestStructFieldMask(t *testing.T) {
mux := runtime.NewServeMux()
pbs.RegisterTestServiceHandlerServer(context.Background(), mux, &pbs.UnimplementedTestServiceServer{})
req := httptest.NewRequest("PATCH", "http://127.0.0.1/test", strings.NewReader(`{"foo": "val1", "struct": {"key1": "val2"}}`))
resp := httptest.NewRecorder()
mux.ServeHTTP(resp, req)
if resp.Code != http.StatusNotImplemented {
body, _ := ioutil.ReadAll(resp.Body)
t.Errorf("Expected Not implemented: Got response %d %q", resp.Code, body)
}
}
Expected behavior
I expected the test to pass.
Actual Behavior
The test fails with the following error:
Expected Not implemented: Got response 400 "{"code":3, "message":"could not find field \"key1\" in \"google.protobuf.Struct\"", "details":[]}"
Your Environment
mac os, grpc gateway v2, go version go1.14 darwin/amd64
Additional Information
For my purpose the ideal behavior would populate the field mask to match the json structure and not depend on the proto structure. For example a request like this:
{
"key1": "val",
"key2": {
"key3":"val2",
"key4": {"key5": "val3"}
}
}
would result in a field mask containing the following paths: key1, key2.key3, key2.key4.key5
regardless if the protos looked like
message item {
string key1 =1;
google.protobuf.Struct key2 = 2;
}
or
message item {
string key1 = 1;
message item2 {
string key3 = 1;
message item3 {
string key5 = 1;
}
item3 key4 = 2;
}
item2 key2 = 2;
}