Fiber 路由匹配采用最长前缀匹配(Trie 树),路径越长、越具体者优先;中间件执行顺序由 app.Use() 位置决定,与路由注册顺序无关;/api/users/:id 比 /api/users 更优先,* 会吞掉所有子路径,StrictRouting 和 CaseSensitive 默认关闭但建议生产开启。

Fiber 路由匹配走的是最长前缀匹配(Trie 树)
Fiber 的路由匹配不看中间件注册顺序,也不按 app.Get() 出现的先后,它底层用压缩前缀树(Trie)做路径查找,核心规则就是:**谁的路径前缀更长、更具体,谁就赢**。比如你同时注册了 /api/users 和 /api/users/:id,那么请求 GET /api/users/123 一定命中后者——不是因为写在后面,而是因为 /api/users/:id 的匹配长度(含通配符)比 /api/users 更精确。
常见错误现象:404 出现在你以为该命中的路由上,其实是因为更长的路径已经“吃掉”了请求。比如误加了 /api/users/:id/profile,它会拦截所有 /api/users/xxx/profile,但你本意只想处理 /api/users/profile 这种扁平结构。
- 路径中
:param和*都参与长度计算,:id算一个段,*算通配整个剩余路径 - 静态路径(如
/health)永远比带参数的同级路径(如/health/:v)优先级低 - Fiber 不支持正则路由,所以没有“自定义优先级”的钩子;想绕过最长匹配,只能靠提前
return或重写app.NewRoute()(不推荐)
Fiber 中间件执行顺序完全由 Use() 调用位置决定
中间件和路由匹配是两套独立机制。Fiber 没有 Priority 字段,也没有“全局 vs 组内优先级”这种抽象。所有 app.Use() 都是全局注册,按代码顺序串成链;而 app.Get("/x", h, mw) 这种路由级中间件,只对当前 handler 生效,且插入位置固定:在所有全局中间件之后、handler 之前。
容易踩的坑:logger 中间件如果写在 auth 后面,那 auth 提前 ctx.Status(401).Send() 并 return,日志就根本打不出来——因为控制流没走到 logger。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 调试时可在每个中间件开头加
fmt.Println("in", "mw-name"),观察实际执行流 - 不要依赖路由组(
app.Group())来调整中间件顺序;它只拼前缀、限作用域,不改变执行时序 - 若需某中间件“插队”,唯一办法是把它挪到
app.Use()列表更靠前的位置
路由冲突时没有自动降级,必须手动干预
Fiber 遇到多条可匹配路由时,不会尝试“次优匹配”或报错提示,而是直接按 Trie 结构返回最长匹配结果。这意味着:如果你注册了 /api/v1/* 和 /api/v1/users,前者会吞掉所有 /api/v1/xxx 请求,包括 /api/v1/users——因为 * 的匹配长度在 Trie 中被算作“无限长”。
这不是 bug,是设计使然。Fiber 认为开发者应明确知道每条路由的覆盖范围。
- 检查冲突最简单的方法:启动服务后访问
http://localhost:3000/debug/routes(需启用fiber.Config{EnablePrintRoutes: true}) - 避免用
*做兜底时,把具体路由放在*之前注册——但注意,Fiber 不保证注册顺序影响匹配顺序,真正起作用的仍是 Trie 节点结构 - 真要实现“fallback”,得在兜底 handler 里手动判断路径,再调用
ctx.Next()或重定向
路径大小写和尾部斜杠默认不敏感,但可关闭
Fiber 默认开启 CaseSensitive: false 和 StrictRouting: false,所以 /API/Users 和 /api/users/ 都能命中 /api/users。这看似方便,但在 API 版本管理或前端路由对接时容易引发歧义。
例如,前端发请求到 /api/v1/users/(带斜杠),后端却只注册了 /api/v1/users(无斜杠),StrictRouting 关闭时能通,打开后就 404。
- 生产环境建议显式配置:
fiber.Config{CaseSensitive: true, StrictRouting: true} - StrictRouting 开启后,
/api和/api/被视为两条不同路由,需分别注册或统一规范前端调用 - CaseSensitive 开启后,
/API和/api不再等价,适合需要区分资源命名风格的场景(如 OpenAPI 规范)
Use() 位置,就足够掌控绝大多数情况。


















