0Pricing
Go Academy · 课时

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 反馈 — 无需本地设置。

此课程中的所有课时

  1. HTTP 中间件链基础
  2. 日志记录与请求 ID 中间件
  3. 身份验证与速率限制中间件
  4. CORS 与 panic 恢复中间件
← 返回 Go Academy