app.use() 是组合中间件的唯一入口,顺序、前缀和参数必须精确;注册顺序决定执行顺序,前缀限定作用域,子应用提供天然隔离,漏调 c.next() 将阻断后续流程。

app.Use() 是组合多个中间件的唯一入口,但顺序、前缀和参数错一个,中间件就可能不执行、不生效,甚至互相覆盖。
中间件注册顺序决定执行顺序
中间件像流水线工位,请求从左到右依次经过。先调用 app.Use(mwA),再调用 app.Use(mwB),那么每个匹配请求一定先走 mwA,再进 mwB。
- 身份验证中间件(如 JWT 验证)必须放在日志中间件之前——否则未授权请求也会打日志,干扰排查
-
cors.New()要早于业务路由,但晚于logger(如果只在 API 组启用)或recover(防 panic 中断) - 不要把
static.New()放在全局无前缀位置,否则所有请求(包括/login)都会先被 static 尝试读文件,拖慢路由匹配
多个中间件可一次注册,但行为不等价于逐个调用
app.Use("/api", logger.New(), cors.New(), jwt.New()) 是合法写法,Fiber 会按顺序将这三个中间件挂载到 /api 前缀下。但它和分三次调用 app.Use("/api", ...) 效果一致,和全局调用 app.Use(logger.New(), cors.New()) 则完全不同。
- 带前缀的批量注册:只对
/api/xxx生效,/health不走任何这仨 - 无前缀批量注册:
app.Use(logger.New(), recover.New())等价于两个独立app.Use(),但它们共享同一层“全局”作用域 - 混用前缀与无前缀会导致作用域混乱——比如
app.Use(logger.New())+app.Use("/api", cors.New()),前者影响所有路径,后者只限/api,但 CORS 不会自动“继承” logger 的上下文
子应用挂载是更彻底的中间件组合方式
当一组中间件+路由逻辑高度内聚(比如整套 OAuth2 流程),用 app.Use("/oauth", oauthApp) 比堆砌中间件更清晰。这里的 oauthApp 是另一个 fiber.App 实例,它内部可自由注册自己的 Use、Get、Post。
- 子应用的中间件只对挂载路径生效,天然隔离作用域,避免和主应用中间件冲突
- 子应用里仍可调用
app.Use("/token", ...),但该前缀是相对于/oauth的,最终匹配的是/oauth/token - 注意:子应用无法直接访问主应用的
c.Locals,需显式透传(例如在挂载中间件里设置c.Locals["db"] = mainDB)
真正容易被忽略的点是:中间件是否“真正执行”,不只看注册顺序,还取决于路径前缀是否匹配、方法是否被 USE 覆盖、以及中间件内部有没有调用 c.Next()。漏掉 c.Next(),后续中间件和路由处理器就永远收不到请求。











