Fiber中间件执行顺序由注册顺序决定:请求时正序执行,响应时倒序执行;logMW必须首个注册以覆盖完整生命周期;路由级中间件在全局之后执行;提前终止需return而非调c.Next()。

Fiber 中间件执行顺序没有“优先级”概念,注册顺序就是运行顺序——写在前面的先执行请求逻辑,后执行响应逻辑;写在后面的后进先出。搞错顺序不是配置问题,是代码调用顺序写反了。
中间件注册顺序 = 请求阶段执行顺序
Fiber 的 app.Use() 是追加到全局中间件切片末尾,按代码出现顺序依次执行。比如:
app.Use(logMW)
app.Use(authMW)
app.Use(rateLimitMW)
app.Get("/api/user", handler)
请求进来时,执行流是:logMW → authMW → rateLimitMW → handler;响应返回时是倒序:rateLimitMW(返回逻辑)→ authMW → logMW。
- 常见错误:把
authMW写在logMW后面,结果鉴权失败时logMW的结束日志根本不会打印——因为authMW调了c.Next()前就 return 或 panic,logMW的响应阶段逻辑被跳过 - 想让日志覆盖完整生命周期,
logMW必须是第一个app.Use() - 别依赖 IDE 自动格式化重排多行
Use()调用,手写时建议每行一个,避免视觉混淆
路由级中间件只对当前路由生效,且在全局中间件之后
Fiber 支持在单个路由上直接挂中间件,例如:app.Get("/admin", adminHandler, authMW, auditMW)。这类中间件会在所有 app.Use() 之后、该路由 handler 之前执行。
- 它不会“覆盖”或“替换”全局中间件,只是追加到该路由专属的中间件链末端
- 若全局已注册
logMW和authMW,再写app.Get("/x", h, auditMW),执行顺序是:logMW→authMW→auditMW→h - 这种写法适合临时增强某条路由,但不适合统一策略——混用容易导致顺序混乱,调试时 log 打印顺序和预期不符
中间件提前终止必须 return,不能靠 c.Next() 控制
Fiber 中间件里不调 c.Next() 就会自然中断后续流程,但很多人误以为要“显式跳过”,反而在拒绝逻辑里也调了 c.Next(),导致 handler 仍被执行。
- 正确做法:鉴权失败时直接
return c.Status(401).Send("unauthorized"),不碰c.Next() - 错误写法:
if !valid { c.Status(401).Send(...); c.Next(); return }——c.Next()会继续触发后续中间件和 handler,造成逻辑泄漏 - 注意:
c.Next()是否继续往下走,取决于当前上下文是否已写入响应体;一旦c.Send()或c.JSON()被调用,Fiber 就认为响应已完成,后续 handler 不会进入
混合标准库中间件时,外层永远先于框架内层
如果你把 Fiber 实例作为 http.Handler 包进标准库中间件,比如 http.ListenAndServe(":8080", stdMW(app)),那 stdMW 就是最外层包装器。
- 此时
stdMW的前置逻辑最先执行,响应阶段最后执行;而整个 Fiber 实例(含所有app.Use())成了它的next - 常见坑:在
stdMW里读c.Request().Context(),但 Fiber 的c.Locals或自定义 context value 是在app.Use()链里设置的,stdMW拿不到 - 跨层共享数据只能靠 HTTP 头、URL 参数或显式透传,别指望标准库中间件能访问 Fiber 的
c.Locals
最易被忽略的一点:Fiber 不做中间件依赖解析,也不支持运行时重排。所谓“动态顺序”只能靠启动时构造中间件链再一次性注入,而不是靠改 app.Use() 调用位置——后者在编译期就固化了执行路径。


















