我似乎无法一起研究如何正确使用中间件和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
}
但我收到错误 undefined:basicAuthHandler 。我理解为什么我会收到错误,但我不知道如何避免错误。我如何向context
提供basicAuthHandler
并仍然在Alice的commonHandlers
列表中使用它?
答案 0 :(得分:1)
您的中间件需要签名
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
,并且应该提供更好的错误响应)