fiber中间件必须是func(*fiber.ctx) error类型,严格签名匹配;需显式调用c.next()才能执行后续处理器,否则中断链;执行顺序由代码书写顺序决定,响应后不可再调c.next()。

自定义中间件在 Fiber 中没有特殊类型或注册接口,它就是标准的 func(*fiber.Ctx) error 函数,不满足这个签名就会编译失败或运行时 panic。
中间件函数签名必须严格匹配 func(*fiber.Ctx) error
这是硬性要求,不是约定。Fiber 的 app.Use()、app.Get() 等方法内部只接受 fiber.Handler 类型(即该签名),其他形式如传值接收 fiber.Ctx、忽略返回值、返回 int 或 string 都会触发类型错误。
- ✅ 正确写法:
func(c *fiber.Ctx) error { return c.Next() } - ❌ 错误写法:
func(c fiber.Ctx) {}(传值,且无返回) - ❌ 错误写法:
func(c *fiber.Ctx) { c.SendString("x") }(缺少error返回) - ⚠️ 注意:即使你只做日志或 header 注入,也必须返回
error;返回nil表示流程继续,非nil会中断链并终止响应
必须显式调用 c.Next() 才能进入下一个处理器
Fiber 不会自动执行后续中间件或路由 handler——是否调用 c.Next() 完全由你控制。这既是灵活性来源,也是常见 bug 根源。
- 不调用
c.Next():当前中间件就是终点,后续所有逻辑(包括路由 handler)都不会执行 - 调用了
c.Next()但前面已写响应(如c.Status(401).Send("no")):可能导致 panic(因响应头已写)或响应被覆盖(body 冲突) - 典型安全中间件写法:
if !authorized { return c.Status(401).Send("unauthorized") }—— 直接 return,不调c.Next()
app.Use() 和路由级中间件的执行顺序完全由代码顺序决定
中间件执行是“栈式入栈、顺序出栈”,没有优先级字段、不按路径深度排序、也不支持自动去重。你写的顺序 = 运行时执行顺序。
-
app.Use(logger)写在最前 → 最先执行 -
app.Use("/api", jwtAuth)在 logger 之后 → 第二个执行(仅对/api前缀生效) -
app.Get("/admin", ipWhitelist, handler)→ipWhitelist在jwtAuth之后、handler之前执行 - ⚠️ 注意:
app.Use("/admin", m1)和app.Get("/admin", m2, h)是两条独立链路,m1对GET /admin生效,m2也生效,顺序取决于它们在代码中出现的位置
最容易被忽略的是:中间件一旦写了响应体或状态码,就绝不能继续调用 c.Next();而是否调用 c.Next() 这个动作本身,决定了整个请求生命周期能否往下走——它不像 Express 那样有隐式 next,这里每一步都是显式的、不可妥协的控制点。











