全书目录

第三十二篇:Gin 完全指南 —— 高速交警中枢宇宙

第七章:中间件 —— 请求不是直接见指挥员,它要先过一串检查站

1 分钟 264 字 第 598 / 962 个阅读单元

Gin 的中间件系统,就是高速交警中枢的灵魂。

你可以把它想成:

text
车辆进站
  │
  ├── 监控记录岗
  ├── 身份核验岗
  ├── 限流检查岗
  ├── 超时控制岗
  ├── 统一错误收口岗
  └── 最终才到业务指挥员
#1. 一个最基本的中间件
go
func OfficerAuth() gin.HandlerFunc {
    return func(c *gin.Context) {
        token := c.GetHeader("X-Officer-Token")
        if token != "traffic-secret" {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
                "error": "无效执勤令牌",
            })
            return
        }

        c.Set("officer_id", "officer-007")
        c.Next()
    }
}

注册:

go
r := gin.Default()
r.Use(OfficerAuth())
#2. c.Next()c.Abort() 是什么
text
c.Next()
= 放车去下一个检查站 / handler

c.Abort()
= 当场拦停,不再继续往后

c.AbortWithStatusJSON(...)
= 拦停 + 直接回执
#3. 中间件链路图
text
请求进入
  │
  ▼
Middleware A
  │  c.Next()
  ▼
Middleware B
  │  c.Next()
  ▼
Handler
  │
  ▼
Middleware B 的后半段
  │
  ▼
Middleware A 的后半段
  │
  ▼
响应发出

这就是为什么很多日志、耗时统计、统一错误处理中间件都会写成这种结构:

go
func AccessLog() gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now()
        c.Next()
        cost := time.Since(start)

        log.Printf("%s %s %d %s",
            c.Request.Method,
            c.Request.URL.Path,
            c.Writer.Status(),
            cost,
        )
    }
}
#4. 一个很重要的工程判断

中间件适合做:

  • 认证
  • 授权
  • 日志
  • Trace ID
  • 限流
  • 超时
  • 统一错误格式
  • 安全头
  • CORS

中间件不适合做:

  • 大段核心业务逻辑
  • 跟某一个具体资源强耦合的流程
  • 到处乱写响应导致链路不清楚的逻辑

检查站应该负责“过站规则”,不是代替值班员把整起案子办完。