如何对所有请求使用gorilla中间件处理程序?

如何对所有请求使用gorilla中间件处理程序?,go,router,mux,Go,Router,Mux,我想使用为记录所有内容指定的处理程序 这就是我所拥有的: r := mux.NewRouter() s := r.PathPrefix("/api/v1").Subrouter() s.HandleFunc("/abc", handler.GetAbc).Methods("GET") s.HandleFunc("/xyz", handler.GetXyz).Methods("GET") 我想使

我想使用为记录所有内容指定的处理程序

这就是我所拥有的:

r := mux.NewRouter()
s := r.PathPrefix("/api/v1").Subrouter()

s.HandleFunc("/abc", handler.GetAbc).Methods("GET")
s.HandleFunc("/xyz", handler.GetXyz).Methods("GET")
我想使用日志中间件,但我不想在每一行中重复它,正如github中所示:

r.Handle("/admin", handlers.LoggingHandler(os.Stdout, http.HandlerFunc(ShowAdminDashboard)))
r.HandleFunc("/", ShowIndex)
有没有一种方法可以将通用日志中间件传递给r,所有通过r路由器的东西都将首先经过中间件?

使用中间件:

func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do stuff here
        log.Println(r.RequestURI)
        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}


r.Use(loggingMiddleware)


这里是文档:

我用一个中间件函数包装了LoggingHandler

func loggingMiddleware(next http.Handler) http.Handler {
    return handlers.LoggingHandler(os.Stdout, next)
}

r.Use(loggingMiddleware)

这是我采取的方法,对我来说效果最好


类型路由结构{
名称字符串
方法字符串
模式串
安全布尔
HandlerFunc http.HandlerFunc
}
键入Routes[]Route
var routes=路由{
路线{
名称:“文件”,
方法:“获取”,
模式:“/v2/docs”,
HandlerFunc:Docs,
},
路线{
名称:“GetUserByName”,
方法:“获取”,
模式:“/v2/user/{username}”,
HandlerFunc:user.GetUserByName,
安全:是的,
},
}
func NewRouter()*mux.Router{
路由器:=mux.NewRouter().StrictSlash(真)
router.NotFoundHandler=http.HandlerFunc(notFound)
router.MethodNotAllowedHandler=http.HandlerFunc(不允许)
对于u,路由:=范围路由{
var处理程序http.handler
如果路线安全{
handler=auth中间件(route.HandlerFunc)
}否则{
handler=route.HandlerFunc
}
handler=handlers.LoggingHandler(os.Stderr,handler)
路由器。
方法(route.Method)。
路径(route.Pattern)。
名称(route.Name)。
处理程序(处理程序)
}
返回路由器
}
func ApplicationRecovery(下一个http.Handler)http.Handler{
返回http.HandlerFunc(func(w http.ResponseWriter,r*http.Request){
延迟函数(){
如果错误:=recover();错误!=nil{
fmt.Fprintln(os.Stderr,“从发生的应用程序错误中恢复”)
_,=fmt.Fprintln(os.Stderr,err)
w、 WriteHeader(http.StatusInternalServerError)
}))
}
}()
next.ServeHTTP(w,r)
})
}
func中间件(下一个http.Handler)http.Handler{
返回http.HandlerFunc(func(w http.ResponseWriter,r*http.Request){
w、 Header().Add(“内容类型”、“应用程序/json”)
next.ServeHTTP(w,r)
})
}
func auth中间件(下一个http.Handler)http.Handler{
返回http.HandlerFunc(func(w http.ResponseWriter,r*http.Request){
//TODO:添加身份验证
log.Println(“需要身份验证”)
next.ServeHTTP(w,r)
})
}
func notFound(w http.ResponseWriter,r*http.Request){
w、 WriteHeader(http.StatusNotFound)
}
不允许使用func(w http.ResponseWriter,r*http.Request){
w、 WriteHeader(http.StatusMethodNotAllowed)
}
func main(){
srv:=http.Server{
地址:“0.0.0.0:8080”,
处理程序:ApplicationRecovery(中间件(NewRouter()),
ReadTimeout:15*次。秒,
WriteTimeout:15*次,秒,
}
log.Fatal(srv.ListenAndServe())
}
通过这种方式,我覆盖了我的基础:

  • 请求执行期间出现死机
  • 为所有请求设置响应头的通用中间件
  • 用于所有请求日志记录的日志中间件
  • 一种安全资源认证中间件
正在运行的处理程序的控制台日志
2020/06/23 22:28:48服务器已启动
2020/06/23 22:28:51需要身份验证
2020/06/23 22:28:51开始x-api-key验证
2020/06/23 22:28:51 x-api-key匹配用户:1
2020/06/23 22:28:51用户1成功访问安全资源
::1---[23/Jun/2020:22:28:51+0100]“DELETE/v2/user/john?permanent=true HTTP/1.1”403 85
更紧凑的解决方案

r.Use(func(next http.Handler) http.Handler { return handlers.LoggingHandler(os.Stdout, next) })

我想用gorilla的LoggingHandler。我用一种有趣的方法把它包在了一个中间件中。这是golang社区的标准还是你“发明”的?我很想承认这一点,这是他们从《狂妄博士》生成骨架的标准。我主要编写API,这些API是契约优先的,这允许我生成基本的服务器结构,不包括中间件。