Hi all,
I am new to Go and would like suggestions on how to share values between middleware.
I currently am writing a JSON body parser middleware for my api and don't really know how to share values to the next handler call. So my code looks something like this:
// BodyParser parses incoming JSON requests
func BodyParser(val {}interface, next http.Handler, w http.ResponseWriter, req *http.Request) error {
type := reflect.TypeOf(val)
val := reflect.New(type).Interface()
err := json.NewDecoder(r.Body).Decode(val)
if (err != nil) {
// handle error here
}
// best way of storing shared middleware value?
next.ServeHTTP(w,r)
return nil
}
I was thinking of using Context, but I read some articles that said using context is a bad idea, so I am wondering if there are other ways of doing it without using Context? Any suggestions would be great, thanks!
评论:
TheMerovius:
freetoplay123:Why do this as a middleware? There seems to be no actual value provided. I'd just use a function
func ParseBody(v interface{}, req *http.Request, res http.ResponseWriter) error { if err := json.NewDecoder(r.Body).Decode(v); err != nil { // handle error here } return nil }
and call that from a handler.
joncalhoun:I didn't know this was the best way of handling JSON request body in Go. Coming from other languages, they always had a JSON parser middleware. Thanks for the info!
freetoplay123:I have mixed feelings about the approach you are taking, but this article may help give you a few ideas - https://www.calhoun.io/pitfalls-of-context-values-and-how-to-avoid-or-mitigate-them/
Context values aren't bad by themselves, and they are pretty useful for middleware, but you just need to use some caution with them and not throw everything under the sun in a context value
If you have follow-up questions let me know - I wrote the linked article.
tgulacsi:Thanks, this gave me a better understanding of Context.
Use a struct and define the handler as method. This way you can store anything on the struct. But I'd prefer the github.com/go-kit/kit way: have a Decoder which decodes the http request, and returns a nicely filled struct; have an Endpoint which receives that processed struct, does its job, then returns another struct with the data to be returned; then have an Encoder, which outputs as needed from the struct into the ResponseWriter.
