-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSONCodec and nil request #121
Comments
Hi, @fridolin-koch, thanks for the report! I think the real issue is that the marshaler is even getting a nil request in the first place. This shouldn't ever happen. I'm guessing the lack of path parameters and lack of query parameters means the initialization of the request to a new, empty message is inadvertently being skipped. |
I'm not sure, I looked at how this is handled in Line 590 in 7aae240
encoding.RegisterCodec(vanguardgrpc.NewCodec(&vanguard.JSONCodec{
MarshalOptions: protojson.MarshalOptions{EmitUnpopulated: true},
UnmarshalOptions: protojson.UnmarshalOptions{DiscardUnknown: true},
}))```
So the error occurs here:
https://github.com/connectrpc/vanguard-go/blob/7aae240d504a5f2ce8aa6cf148232fcbf88eaf36/vanguardgrpc/vanguardgrpc.go#L94-L100
Since `protojson.Unmarshal` (like `json.Unmarshal`) does not work with `nil` as input, it could be fixed like that:
```go
func (g *grpcCodec) Unmarshal(data []byte, v any) error {
msg, ok := v.(proto.Message)
if !ok {
return fmt.Errorf("value is not a proto.Message: %T", v)
}
if data == nil {
return nil
}
return g.codec.Unmarshal(data, msg)
} Another option would be to add some logic to the transcoder that transform |
So I think the fix is to add a case checking for empty requests as needing request prep in protocol_rest.go Line 139 in 7aae240
The request prep correctly handles empty requests. func (r restClientProtocol) requestNeedsPrep(op *operation) bool {
return len(op.restTarget.vars) != 0 ||
len(op.request.URL.Query()) != 0 ||
op.restTarget.requestBodyFields != nil ||
restHTTPBodyRequest(op) ||
restHTTPBodyRequestIsEmpty(op)
}
// This check enables request prep.
func restHTTPBodyRequestIsEmpty(op *operation) bool {
return op.request.ContentLength < 0
} It's actually a fairly rare case as almost anything like a query param or path variable will already trigger the client prep. |
Hello, first of all, cool project! I predict it will be very useful in the future :)
I was tinkering around a bit and noticed an issue with the REST translation. Consider the following gRPC service definition:
I should be able to issue a
GET /v1/schedules
request, without any parameters (i.e. empty request). Unfortunately this fails, sincenil
is then passed to protojson, which fails as it won't handlenil
(IIRC it's an intentional design decision).My suggestion to handle that would be to either treat
nil
as{}
or to not callUnmarshal
if the input is nil. Naively I'd change it here:vanguard-go/codec.go
Line 212 in 7aae240
Not sure if this is the best place to change this.
Best Regards,
Frido
The text was updated successfully, but these errors were encountered: