Fiber中间件执行时机、作用域和路径匹配逻辑与直觉不同:app.Use是前缀拦截器,只拦截不响应;Group.Use仅限本组路由;Timeout已弃用,须手动SetDeadline并显式检查DeadlineExceeded。

别直接往 app.Use 里塞函数就以为中间件生效了——Fiber 的中间件执行时机、作用域和路径匹配逻辑,和你直觉想的很可能不一样。
app.Use 是前缀拦截器,不是路由注册器
app.Use 只做一件事:对所有以指定路径前缀开头的请求(不管什么 HTTP 方法),先执行中间件逻辑,再放行进路由匹配。它不注册任何 handler,也不参与路径参数解析。
- 写
app.Use("/api", middleware)→ 匹配/api/users、/api/v1/login、/api/xxx/yyy,但不匹配/users - 写
app.Use(middleware)(无路径)→ 对所有请求生效,等价于全局中间件 - 常见错误:在
app.Use("/api")后没接任何 handler,结果所有/api/*请求都 404 —— 因为它只拦截,不响应 - 注意:
app.Use("/api")和app.Group("/api")完全不同:前者是“路过即拦”,后者是“新建子树”
Group.Use 只对本组内路由生效,且无法按方法过滤
app.Group("/admin").Use(auth) 表示:所有注册在该分组下的 Get、Post、Put 等路由,都会经过 auth;但它不会影响根路由或其他分组,也不能跳过某个方法。
- 如果你只想对
POST /admin/users限流,而GET /admin/users不限,不能靠Group.Use(limiter)实现——它对两者都生效 - 正确做法:拆成两个分组,或改用路由级中间件,如
admin.Post("/users", limiter, handler) - 鉴权中间件必须在限流之前注册,否则
limiter拿不到c.Locals("role"),只能 fallback 到 IP 限流 - 嵌套
Group(如app.Group("/v1").Group("/admin"))会让路径和中间件顺序变难调试,建议用单层变量定义前缀,例如v1admin := app.Group("/v1/admin")
超时中间件不能全局挂,Timeout 已弃用
Fiber 的 fiber.Timeout 中间件在 v2.5+ 和 v3.x 中已标记为 deprecated,调用后完全不生效。官方文档还没删,但源码里就是个空函数。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
立即学习“go语言免费学习笔记(深入)”;
- 真正有效的做法是:在每个 handler 开头手动调
c.Context().SetDeadline(time.Now().Add(2 * time.Second)) - 必须写在 handler 函数第一行,中间件里设无效——因为每个请求的
c.Context()是独立实例 - 下游调用(DB、HTTP client)也得各自设 deadline,比如
db.QueryRowContext(c.Context(), ...),否则超时只卡在 handler 层 - 超时触发后,
c.Context().DeadlineExceeded()会返回 true,但 handler 仍会继续执行——必须显式if c.Context().DeadlineExceeded() { return },否则可能写一半响应、连 DB 都没清理
c.Params、c.QueryParam、c.BodyParser 三者互不干扰,混用必空
它们读取的数据来源完全不同,没有 fallback 关系。写错位置,值永远是零值,还不会报错。
-
c.Params("id")只从路径占位符提取,比如app.Get("/user/:id")匹配/user/123才能取到"123";对/user?id=123或 JSON body 无效 -
c.QueryParam("q")只读 URL query string,比如/search?q=golang→"golang";不碰 header、body、path -
c.BodyParser(&v)是专为application/json设计的,且必须传结构体地址(&v),不是v;若 Content-Type 是application/x-www-form-urlencoded,得用c.FormValue("name") - 常见坑:
c.BodyParser(v)(漏&)→ 编译通过但解析失败,v始终为空;c.Params("id")在app.Get("/user")下调用 → 返回空字符串,不是 error
最易被忽略的一点:Fiber 的 c.Context() 是 fasthttp 自研 context,不兼容标准库 context.WithTimeout,c.Context().Done() 永远不会因 Timeout 中间件触发。所有超时控制必须靠 SetDeadline + DeadlineExceeded 显式判断,少一步就失效。


















