在我的AuthMw中间件中,我想进行数据库调用。
我的数据库变量在main中初始化,如何将其传递给我的中间件AuthMw?
func main() {
db, err := gorm.Open("postgres", ... )
r := mux.NewRouter()
r.Handle("/ws", serveWebsocket(hub))
r.Use(AuthMw)
//
//
...
} // main
func AuthMw(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.URL.Query().Get("token")
fmt.Printf("AuthMiddleware token is: %v\n", token)
ctx := ....
next.ServeHTTP(w, r.WithContext(ctx))
})
}
答案 0 :(得分:7)
您有两个直接选项,不涉及全局变量。
您可以将AuthMw
重写为:
func AuthMw(db *DbType) (func (next http.Handler) http.Handler) {
return func (next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Your code goes here, now with a pointer to db
})
}
}
这样,你就可以制作一个"工厂功能"返回一个新的http.Handler
装饰器,通过闭包可以访问您的db
变量。
此后您需要做的就是将r.Use(AuthMw)
替换为r.Use(AuthMw(db))
。
这可能对嵌套方法有点重,所以我反而建议......
将AuthMw
转换为一个结构,并附上装饰器作为方法:
type AuthMw struct {
db *DbType
}
func NewAuthMw(db *DbType) AuthMw {
return AuthMw{db}
}
func (a *AuthMw) Decorator(next http.Handler) http.Handler {
// Your code, now with a pointer to db, goes here
}
然后您只需要将r.Use(AuthMw)
替换为r.Use(authMwVariable.Decorator)
。