-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
I'm encountering the same problem described in #1673 and would like to provide more context and a concrete proposal.
Problem:
Given a proto like:
syntax = "proto3";
package example;
import "google/protobuf/empty.proto";
import "google/api/annotations.proto";
option go_package = "examplepb";
// Request message with a repeated string field
message MyRequest {
repeated string items = 1;
}
// Service definition with HTTP annotation
service MyService {
rpc SendItems(MyRequest) returns (google.protobuf.Empty) {
option (google.api.http) = {
patch: "/v1/items"
body: "*"
};
}
}
When sending a request with an empty array in JSON (e.g., curl -X PATCH -d '{"items":[]}' localhost:7777/v1/items
), the generated Go gRPC handler receives nil
for the items
field, not an empty slice. This is not due to sending null
, but specifically an empty array.
Constraints:
- Wrapping the field in a message is not an option, as the proto definitions are already published and used for OpenAPI generation.
- Customizing the gateway marshaler does not help, since the protobuf encoding treats both
nil
and empty slices asnil
in the generated Go code, so the handler cannot distinguish between omitted and explicitly empty arrays.
Proposal:
-
Use a custom
runtime.WithMetadata
option in grpc-gateway. When the HTTP request reaches the gateway, parse the body and record the paths of empty array fields (including nested fields) in the context metadata.- Example implementation: https://gist.github.com/zhangcz828/e1606cd5dadf1ae175c5cacd3fab4b44
-
Add a gRPC interceptor that reads the
x-empty-fields
metadata, and uses reflection to set the corresponding fields in the request struct to their type's empty value (e.g., set a string slice to[]string{}
).- Supports nested field paths (e.g.,
"foo.bar.items"
). - Handles mapping between JSON field names and Go struct fields generated from proto (case-insensitive, supports snake_case and camelCase).
- Example implementation: https://gist.github.com/zhangcz828/0a8f8639b9ff0d376c919b7ef4da6d3a
- Supports nested field paths (e.g.,
Question:
Would this approach to handling "nullable" or explicitly empty repeated fields be acceptable for inclusion in this repo, so that other projects can benefit from it? Feedback and suggestions are welcome.