答案是通过函数包装和责任链模式将多个中间件串联,每个中间件处理特定逻辑并决定是否调用下一个;Go中中间件为接收http.Handler并返回新Handler的函数,可手动嵌套或使用chainMiddleware组合,执行顺序遵循后进先出的洋葱模型。

在Go语言中实现路由中间件链的核心思路是通过函数包装和责任链模式,将多个中间件依次封装到HTTP处理器中。每个中间件负责处理特定逻辑(如日志、认证、CORS等),然后决定是否调用下一个中间件。下面是一个清晰、实用的实现方式。
中间件的基本结构
Go的中间件通常是一个函数,接收 http.Handler 并返回一个新的 http.Handler。这种设计允许你将多个中间件串联起来。
示例:定义一个日志中间件:
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
构建中间件链
你可以手动嵌套调用中间件,也可以封装一个工具函数来简化链式调用。
立即学习“go语言免费学习笔记(深入)”;
手动方式:
handler := loggingMiddleware(authMiddleware(finalHandler))
更优雅的方式是使用组合函数:
func chainMiddleware(mw ...func(http.Handler) http.Handler) func(http.Handler) http.Handler {
return func(final http.Handler) http.Handler {
result := final
for i := len(mw) - 1; i >= 0; i-- {
result = mw[i](result)
}
return result
}
}
使用时:
middlewareChain := chainMiddleware(loggingMiddleware, authMiddleware, corsMiddleware)
http.Handle("/api/", middlewareChain(apiHandler))
实际应用场景
常见中间件包括:
- 日志记录:打印请求方法、路径、耗时
- 身份验证:检查Token或Session
- CORS处理:设置响应头支持跨域
- 错误恢复:捕获panic并返回500
- 限流:控制请求频率
每个中间件只关注单一职责,便于测试和复用。
基本上就这些。通过函数式组合,Go能非常简洁地实现灵活的中间件链,无需依赖框架也能写出清晰可维护的代码。关键是理解 http.Handler 的接口能力和函数的高阶用法。不复杂但容易忽略的是中间件的执行顺序——后添加的先执行(洋葱模型)。











