中间件执行顺序由注册方式和位置严格决定,漏掉c.Next()或放错位置会导致链断裂;全局中间件须用r.Use()注册在gin.Engine上;分组中间件需正确绑定到Group实例;单路由中间件仅对当前接口生效;c.Next()是洋葱模型核心,控制流程暂停与恢复。

中间件执行顺序由注册方式和位置严格决定,不是“写在哪就从哪开始”,漏掉 c.Next() 或放错位置会导致整个链断裂。
全局中间件必须用 r.Use() 注册在 gin.Engine 上
只有 r.Use(middleware) 才会让中间件参与所有路由的处理链开头。常见错误是误把中间件塞进某个 GET() 里,以为“加了就全局生效”——实际它只对该接口起作用。
-
gin.Default()已内置gin.Logger()和gin.Recovery(),重复Use()会多打一次日志、多套一层 panic 捕获 - 若用
gin.New(),必须手动Use()这两个中间件,否则无请求日志、panic 直接崩溃 - 多个
Use()按调用顺序追加:r.Use(A); r.Use(B)→ 执行顺序为 A → B → handler
路由组中间件要绑定到 Group() 实例,不能链式丢失引用
写成 r.Group("/api").Use(mw).GET(...) 是错的:虽然语法合法,但 Use() 返回的是分组实例,GET() 却调用在根路由上,导致中间件没生效。
- 正确写法一(参数式):
api := r.Group("/api", AuthMiddleware(), LoggerMiddleware()) - 正确写法二(显式调用):
api := r.Group("/api"); api.Use(AuthMiddleware()).Use(LoggerMiddleware()) - 分组中间件只影响该组下所有子路由,比如
/api/users、/api/orders,不波及/health
单路由中间件直接放在 GET() 等方法的 handler 前面
这种写法只对当前接口生效,适合做接口级限流、调试钩子或特殊校验。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 写法:
r.POST("/upload", RateLimitMiddleware(), uploadHandler) - 多个中间件按从左到右顺序执行:
RateLimitMiddleware → AuthMiddleware → uploadHandler - 中间件函数必须是
gin.HandlerFunc类型;闭包返回值未强制转类型会编译报错或运行时 panic
c.Next() 是流程控制核心,不是“调用下一个函数”
c.Next() 的作用是让当前中间件暂停,把控制权交给后续中间件或 handler,等它们全部执行完再回来继续跑 c.Next() 后面的代码——这是洋葱模型的关键。
- 漏写
c.Next():后续所有中间件和 handler 都不会执行,请求卡死 - 写在中间件开头后立刻 return:等效于没写,同样中断流程
- 写在
c.Abort()之后:无意义,Abort()已终止链,Next()不再触发 - 典型结构:
preCheck(); c.Next(); postLog(),前置校验 + 放行 + 后置记录
最容易被忽略的是 c.Next() 的语义——它不返回值、不阻塞、不抛异常,panic 发生时它后面的代码仍会执行。真要中断流程,必须显式调用 c.Abort() 或 c.AbortWithStatusJSON(),而不是靠跳过 Next() 来“隐式拦截”。










