I'm using a library (go-kit) which requires I specify functions to encode / decode my request and response types to/from JSON. For encoding, it is simple:
func EncodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
return json.NewEncoder(w).Encode(response)
}
I pass this function to create the HTTP server and it works fine. However, their proposed approach for requests is to make a separate function of the form:
func decodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
var req UppercaseRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return req, nil
}
For every single RPC in my application. I would really like to keep my code DRY and avoid having hundreds of almost identical methods. As such, I attempted to write a function to generate closures that decode the given request type:
func DecodeRequest(req interface{}) httptransport.DecodeRequestFunc {
return func(_ context.Context, r *http.Request) (interface{}, error) {
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
return nil, err
}
return req, nil
}
}
This function can be called like so:
DecodeRequest(UppercaseRequest{}}
Unfortunately, when I do so, the JSON decoding fails, even though the type of req is in fact mypackage.UppercaseRequest. I'm not sure where to go from here. Is there a way I can avoid having to write a method per request type? Is there some way I can help the Decode function understand what this type is at runtime? Thanks in advance!
Here is a go playground demonstrating the issue: https://play.golang.org/p/GgHsLffp1G