Go 手写 net/http 中间件链:从零拼一条可组合的请求管道
test12026-10-131 次阅读
框架不是必须的
net/http 的 http.Handler 就是一个函数签名,中间件本质上是一个"接收 handler、返回 handler"的函数。自己拼一条链,逻辑完全透明,也更容易理解 Gin、Echo 这类框架底层在做什么。小型服务或内部工具完全可以只靠标准库。
中间件的定义
type Middleware func(http.Handler) http.Handler
func Logging(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Printf("%s %s %v", r.Method, r.URL.Path, time.Since(start))
})
}
写一个鉴权中间件
func Auth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") == "" {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
把中间件串成链
用一个工具函数把多个中间件从外到内嵌套起来,最左边的先执行、最右边的最后包裹业务 handler。
func Chain(h http.Handler, mws ...Middleware) http.Handler {
for i := len(mws) - 1; i >= 0; i-- {
h = mws[i](h)
}
return h
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/api/hello", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "hello")
})
handler := Chain(mux, Logging, Auth)
http.ListenAndServe(":8080", handler)
}
小结
- 中间件签名统一为 func(http.Handler) http.Handler,可独立测试。
- Chain 从后往前包裹,最左边的外层中间件先拿到请求。
- 不依赖框架也能拥有清晰、可组合的横切逻辑。
T
test1
文章作者
框架不是必须的 net/http 的 http.Handler 就是一个函数签名,中间件本质上是一个"接收 handl...
- 分类
- 技术
- 发布时间
- 2026-10-13
- 字数
- 约 1328 字
- 阅读
- 1 次
