Sharing values between middleware

xuanbao · 2017-08-15 07:00:08 · 739 次点击    
这是一个分享于 2017-08-15 07:00:08 的资源,其中的信息可能已经有所发展或是发生改变。

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:

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.

freetoplay123:

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!

joncalhoun:

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.

freetoplay123:

Thanks, this gave me a better understanding of Context.

tgulacsi:

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.


入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

739 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传