go - 使用 Alice 和 HttpRouter 的中间件

标签 go middleware go-alice

我似乎不知道如何正确地一起使用中间件和 Http Router。

我的代码是:

type appContext struct {
  db *mgo.Database
}

func main(){
  c := appContext{session.DB("db-name")}
  commonHandlers := alice.New(context.ClearHandler, basicAuthHandler)

  router := NewRouter()
  router.Post("/", commonHandlers.ThenFunc(c.final))

  http.ListenAndServe(":5000", router)
}

最终中间件是:

func (c *appContext) final(w http.ResponseWriter, r *http.Request) {
  log.Println("Executing finalHandler")
  w.Write([]byte("TESTING"))
}

但我希望我的 basicAuthHandler 成为 commonHandlers 的一部分。它还需要 context 以便我可以查询数据库。

我试过这个:

func (c *appContext) basicAuthHandler(w http.ResponseWriter, r *http.Request) {
  var app App
  err := c.db.C("apps").Find(bson.M{"id":"abcde"}).One(&app)
  if err != nil {
    panic(err)
  }

  //do something with the app
}

但我收到错误 undefined: basicAuthHandler。我明白为什么我会收到错误,但我不知道如何避免它。我怎样才能将 context 提供给 basicAuthHandler 并且仍然在 Alice 的 commonHandlers 列表中使用它?

最佳答案

你的中间件需要有签名

func(http.Handler) http.Handler

通过这种方式,您的中间件将包装处理程序,而不仅仅是提供最终处理程序。您需要接受一个 http.Handler,执行任何需要完成的处理,然后在链中的下一个处理程序上调用 ServeHTTP。您的 basicAuthHandler 示例可能如下所示:

func (c *appContext) basicAuthHandler(h http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        var app App
        err := c.db.C("apps").Find(bson.M{"id": "abcde"}).One(&app)
        if err != nil {
            panic(err)
        }
        h.ServeHTTP(w, r)

    })
}

(尽管您不想在您的应用中 panic ,并且应该提供更好的错误响应)

关于go - 使用 Alice 和 HttpRouter 的中间件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30331759/

相关文章:

image - 使用 image/jpeg 编码会导致图像饱和/像素错误

go - 在go中合并两个结构(相同类型)?

go - 在goLang中使用julienschmidt/httprouter时如何使用中间件?

php - Slim v3 使用自定义类添加中间件

go - 如何将 Go 中间件模式与错误返回请求处理程序结合起来?

go - 从 slice 创建复选框组

middleware - GET 以外的代理请求与 NestJS 和 http-proxy-middleware 挂起

go - 将自定义中间件类型传递给alice.New()函数时,构建失败

go - bcrypt 生成不正确的哈希 - 我的用户输入处理是否正确?