HTTP 中间件链基础
包装 http.Handler,并使用 next 链接中间件
HTTP 中间件链基础 是 CoddyKit 上的免费 Go Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。
net/http 中的中间件
在 Go 标准库中,中间件是一个接收 http.Handler 并返回新的 http.Handler 的函数,新处理程序会在原处理程序外层包装额外行为。
type Middleware func(http.Handler) http.Handler基本中间件
内部的 HandlerFunc 会在原处理程序外层包装前置和后置逻辑:
func Logger(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)
log.Printf("← %s %s done", r.Method, r.URL.Path)
})
}应用中间件
在向多路复用器注册处理程序之前先进行包装:
mux := http.NewServeMux()
mux.Handle("/api/", Logger(Auth(apiHandler)))
http.ListenAndServe(":8080", mux)中间件链辅助函数
链函数会以清晰的从左到右顺序应用多个中间件:
func Chain(h http.Handler, ms ...func(http.Handler) http.Handler) http.Handler {
for i := len(ms)-1; i >= 0; i-- { h = ms[i](h) }
return h
}
// Usage: Chain(handler, Logger, Auth, RateLimit)中间件中的上下文
通过创建派生上下文并包装请求,附加请求作用域内的值:
func RequestID(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := uuid.New().String()
ctx := context.WithValue(r.Context(), reqIDKey, id)
w.Header().Set("X-Request-ID", id)
next.ServeHTTP(w, r.WithContext(ctx))
})
}响应写入器包装器
通过包装 ResponseWriter,捕获处理程序写入的状态码:
type captureWriter struct {
http.ResponseWriter
status int
}
func (cw *captureWriter) WriteHeader(code int) {
cw.status = code
cw.ResponseWriter.WriteHeader(code)
}恐慌恢复中间件
从恐慌中恢复,以防止服务器崩溃:
func Recovery(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if rec := recover(); rec != nil {
http.Error(w, "Internal Server Error", 500)
}
}()
next.ServeHTTP(w, r)
})
}顺序很重要
中间件按照其包装处理程序的顺序运行。Recovery 应位于最外层(包装所有内容)。身份验证应位于业务逻辑之前。日志记录通常位于 Recovery 之后的最外层。
与第三方路由器的兼容性
由于中间件遵循标准的 func(http.Handler) http.Handler 签名,因此它兼容 chi、gorilla/mux 以及任何接收 http.Handler 的路由器。
全局中间件与特定路由中间件
可以将中间件全局应用于整个多路复用器,也可以包装单个处理程序以实现特定路由的行为。chi 的子路由器可以更清晰地实现路由组级别的中间件。
测试中间件
使用 httptest.NewRecorder 和 httptest.NewRequest,无需启动真实服务器即可单独测试中间件。
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/", nil)
Logger(http.HandlerFunc(noop)).ServeHTTP(w, r)快速检查
标准的 net/http 中间件签名是什么?
回顾:中间件链
关键要点:
- func(http.Handler) http.Handler 是标准签名
- 使用 Chain 辅助函数,避免深层嵌套
- 使用 r.WithContext(ctx) 附加值;使用捕获写入器记录状态
- Recovery 位于最外层;身份验证位于业务逻辑之前;日志记录位于 Recovery 之后
常见问题解答
「HTTP 中间件链基础」课时是免费的吗?
是的 — 「HTTP 中间件链基础」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。
「HTTP 中间件链基础」这节课中我会学到什么?
包装 http.Handler,并使用 next 链接中间件 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Go Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「HTTP 中间件链基础」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Go Academy 课中编写并运行代码吗?
能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- HTTP 中间件链基础
- 日志记录与请求 ID 中间件
- 身份验证与速率限制中间件
- CORS 与 panic 恢复中间件