本文介绍golang标准库HTTP middleware的写法。
目录1. http.Handler
与http.HandlerFunc
http.Handler
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
http.HandlerFunc
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
1.1 结构体 实现 http.Handler
type SingleHost struct {
handler http.Handler
allowedHost string
}
func (s *SingleHost) ServeHTTP(w http.ResponseWriter, r *http.Request) {
host := r.Host
if host == s.allowedHost {
s.handler.ServeHTTP(w, r)
} else {
w.WriteHeader(403)
}
}
// handler := SingleHost{handler, allowedHost}
1.2 高阶函数
func SingleHost(handler http.Handler, allowedHost string) http.Handler {
ourFunc := func(w http.ResponseWriter, r *http.Request) {
host := r.Host
if host == allowedHost {
handler.ServeHTTP(w, r)
} else {
w.WriteHeader(403)
}
}
return http.HandlerFunc(ourFunc)
}
// handler := SingleHost(handler, allowedHost)
2. github.com/justinas/alice:
将Middleware1(Middleware2(Middleware3(App)))
变为alice.New(Middleware1, Middleware2, Middleware3).Then(App)
type Constructor func(http.Handler) http.Handler
type Chain struct {
constructors []Constructor
}
func New(constructors ...Constructor) Chain {
return Chain{append(([]Constructor)(nil), constructors...)}
}
func (c Chain) Then(h http.Handler) http.Handler {
for i := range c.constructors {
h = c.constructors[len(c.constructors)-1-i](h)
}
return h
}
参考: https://justinas.org/writing-http-middleware-in-go#usecases