Skip to content

FieldMask Generation causes a 400 when a google.protobuf.Struct field has populated values #1570

Closed
@talanknight

Description

@talanknight

🐛 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;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions