Fiber默认StrictRouting:true,/users和/users/是两条独立路由,只注册前者则后者404;关闭StrictRouting会导致/users/:id等参数路由被静态路由错误匹配,推荐显式注册或重定向中间件。

直接用 fiber.New() 初始化,别碰 fiber.Default();StrictRouting 默认开启是设计契约,不是 bug,关它只会让路由行为更难预测。
为什么 /users 和 /users/ 都 404?
Fiber 默认 StrictRouting: true,路径末尾斜杠参与匹配。注册了 app.Get("/users", h),就只响应 GET /users;/users/ 是另一条未注册的路由,自然 404。
- 别用
fiber.New(&fiber.Config{StrictRouting: false})临时修复——关闭后/users/123可能被/users错误捕获,c.Params("id")拿不到值 - 显式注册两条:同时写
app.Get("/users", h)和app.Get("/users/", redirectHandler) - 或统一加中间件重定向:
if strings.HasSuffix(c.Path(), "/") && c.Path() != "/" { c.Redirect(strings.TrimSuffix(c.Path(), "/"), 301) } - 上线前同步检查前端 SDK、OpenAPI spec、Postman 集合是否全用无尾斜杠路径
c.Params()、c.QueryParam()、c.BodyParser() 别混用
三者读取来源完全隔离,参数名相同也不互通:
-
c.Params("id")只从路径占位符提取,如app.Get("/user/:id", h)匹配/user/123后才可取到"123" -
c.QueryParam("q")只读?q=go这类 query string,对路径或 body 无效 -
c.BodyParser(&v)是解析 JSON body 的正解;若 content-type 是application/x-www-form-urlencoded,得换c.FormValue("name") - URL 是
/user/123?format=json,那么c.Params("id") == "123",c.QueryParam("format") == "json",两者互不干扰
app.Use() 和 app.Group() 的本质区别
app.Use() 是前缀级中间件挂载,app.Group() 是独立路由树节点:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
立即学习“go语言免费学习笔记(深入)”;
-
app.Use("/api", mw)→ 匹配/api、/api/users、/api/v1/health,但不匹配/apixxx或/api123(后面不是/或路径结束) -
api := app.Group("/api")返回新*fiber.Router,后续必须写全路径:api.Get("/users", h)注册的是GET /api/users - 常见错误:
api.Get("/api/users", h)→ 实际注册成/api/api/users,多了一层前缀 - 组内中间件(如
api.Use(auth))只影响该组下的所有路由,不影响根路由或其他组
路由注册必须在 app.Listen() 前完成
Fiber 的 Radix 树启动后冻结,运行时无法动态修改:
- 所有
app.Get()、app.Post()必须放在main()顶部或初始化函数中,app.Listen()之前 - API 网关类场景需“按租户加载路由”?不能运行时注册,得预加载全量路由 + handler 内部逻辑分发
- 闭包里捕获的
map或slice不是线程安全的,哪怕只读也要加sync.RWMutex - 正则通配符
*路由(如app.Get("/user/*", h))性能差 3–5 倍,绕过 Radix 树最优路径,退化为线性扫描
最易被忽略的点:StrictRouting 不是开关,而是契约;你改配置不如改约定——前端、文档、测试集合、后端注册全部对齐无尾斜杠,比任何中间件都可靠。


















