我似乎想不出如何将中间件和Http路由器正确地结合在一起。
我的代码是:
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
}但是我得到了未定义的错误:basicAuthHandler。我明白为什么我会犯这个错误,但我不知道如何避免。我如何将context提供给basicAuthHandler,并且仍然在commonHandlers列表中使用它呢?
发布于 2015-05-19 17:06:30
您的中间件需要有签名。
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,并且应该提供更好的错误响应)
https://stackoverflow.com/questions/30331759
复制相似问题