减少多路复用器中间件和自定义上下文实现中的样板
Reducing boilerplate in a mux middlware and custom context implementation
我是 Go 的新手,正在尝试在我在 mux
之上构建的网关库中创建中间件实现。到目前为止,我想出了这个:
type (
MyContext struct {
// ...
}
APIGateway struct {
mux *mux.Router
ctx *MyContext
}
)
type MiddlewareFunc func(*MyContext) func(http.Handler) http.Handler
func (a APIGateway) Use(mw MiddlewareFunc) {
a.mux.Use(mw(ctx))
}
这可行,但我必须处理大量样板代码。在此模式上实现的最简单的中间件必须至少有两个 return 语句和大量倾斜函数声明。
func someMiddleware(ctx *MyContext) func(http.Handler) http.Handler {
return func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Application Logic here
handler.ServeHTTP(w, r)
})
}
}
当中间件必须采用一些额外的参数时,这很快就会成为一个更大的问题,因为现在它必须处理三个 return 语句:
func LogginMiddleware(c LoggerConfig) MiddlewareFunc {
return func(ctx *MyContext) func(http.Handler) http.Handler {
return func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// ...
handler.ServeHTTP(w, r)
// ...
})
}
}
}
有什么方法可以减少样板代码的参与?
您遇到这个问题是因为中间件函数是作为闭包实现的。注意中间件函数定义为:
type MiddlewareFunc func(http.Handler) http.Handler
其中 http.Handler
是一个接口。所以你可以为每个中间件写这样的东西:
type MyMiddleware struct {
// Fields your middleware func needs
Next http.Handler
}
// This is the middleware func
func MW(next http.Handler) http.Handler {
m:=MyMiddleware{Next:next}
// Initialize other fields
return m
}
// Implement http.Handler.
func (m MyMiddleware) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
// Do middleware stuff
m.Next.ServeHTTP(w,req)
}
我是 Go 的新手,正在尝试在我在 mux
之上构建的网关库中创建中间件实现。到目前为止,我想出了这个:
type (
MyContext struct {
// ...
}
APIGateway struct {
mux *mux.Router
ctx *MyContext
}
)
type MiddlewareFunc func(*MyContext) func(http.Handler) http.Handler
func (a APIGateway) Use(mw MiddlewareFunc) {
a.mux.Use(mw(ctx))
}
这可行,但我必须处理大量样板代码。在此模式上实现的最简单的中间件必须至少有两个 return 语句和大量倾斜函数声明。
func someMiddleware(ctx *MyContext) func(http.Handler) http.Handler {
return func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Application Logic here
handler.ServeHTTP(w, r)
})
}
}
当中间件必须采用一些额外的参数时,这很快就会成为一个更大的问题,因为现在它必须处理三个 return 语句:
func LogginMiddleware(c LoggerConfig) MiddlewareFunc {
return func(ctx *MyContext) func(http.Handler) http.Handler {
return func(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// ...
handler.ServeHTTP(w, r)
// ...
})
}
}
}
有什么方法可以减少样板代码的参与?
您遇到这个问题是因为中间件函数是作为闭包实现的。注意中间件函数定义为:
type MiddlewareFunc func(http.Handler) http.Handler
其中 http.Handler
是一个接口。所以你可以为每个中间件写这样的东西:
type MyMiddleware struct {
// Fields your middleware func needs
Next http.Handler
}
// This is the middleware func
func MW(next http.Handler) http.Handler {
m:=MyMiddleware{Next:next}
// Initialize other fields
return m
}
// Implement http.Handler.
func (m MyMiddleware) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
// Do middleware stuff
m.Next.ServeHTTP(w,req)
}