Gin 的中间件系统,就是高速交警中枢的灵魂。
你可以把它想成:
车辆进站
│
├── 监控记录岗
├── 身份核验岗
├── 限流检查岗
├── 超时控制岗
├── 统一错误收口岗
└── 最终才到业务指挥员#1. 一个最基本的中间件
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()
}
}注册:
r := gin.Default()
r.Use(OfficerAuth())#2. c.Next() 和 c.Abort() 是什么
c.Next()
= 放车去下一个检查站 / handler
c.Abort()
= 当场拦停,不再继续往后
c.AbortWithStatusJSON(...)
= 拦停 + 直接回执#3. 中间件链路图
请求进入
│
▼
Middleware A
│ c.Next()
▼
Middleware B
│ c.Next()
▼
Handler
│
▼
Middleware B 的后半段
│
▼
Middleware A 的后半段
│
▼
响应发出这就是为什么很多日志、耗时统计、统一错误处理中间件都会写成这种结构:
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
中间件不适合做:
- 大段核心业务逻辑
- 跟某一个具体资源强耦合的流程
- 到处乱写响应导致链路不清楚的逻辑
检查站应该负责“过站规则”,不是代替值班员把整起案子办完。