简介
中间件(middleware)是责任链模式的一种实现,在后端常用于Request与业务代码之间的一些信息处理,如身份获取、权限校验、日志记录、响应处理等,有效对业务代码进行隔离,并使中间处理代码模块化,条理更清晰。
责任链模式的核心思想为:
- 不同职责模块接收和返回的参数相同,便于模块之间的组合调用。
- 最终业务代码作为
next函数被包裹进职责模块组合的最深处。
实现:
type MidHandler func(func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request)
func (m MidHandler) Use(h MidHandler) MidHandler {
return func(next func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return h(m(next))
}
}
func (m MidHandler) Run(h func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return m(h)
}
- 测试:
func main() {
m := MidHandler(func(next func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("mid1")
next(w, r)
}
}).Use(func(next func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
next(w, r)
fmt.Println("mid2")
}
}).Use(func(next func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
next(w, r)
fmt.Println("mid3")
}
})
http.HandleFunc("/", m.Run(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("123")
}))
http.ListenAndServe(":8888", nil)
}
- 测试结果:
mid1
123
mid2
mid3
- 试试 Go 自带的 BasicAuth
MidHandler(func(next func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if _, password, ok := r.BasicAuth(); ok && password == "123456" {
next(w, r)
} else {
w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
}
}
})
还在用数组存储中间件函数?那也太low了。