fiber支持*通配符(如/user/*匹配/user/a、/user/a/b,不匹配/user/)、正则路径(如/user/(?d+))及app.all("*", h)兜底匹配;*仅捕获非空路径段,需注意注册顺序与参数拷贝。

通配符路由匹配:Fiber 支持哪些写法
Fiber 的路由系统基于 fasthttp,不支持 Gin 那种 :id 命名参数的语法(如 /user/:id),但原生支持通配符 * 和正则表达式路径匹配。它用的是线性路由栈 + 路径解析器,所以通配符行为更接近“前缀捕获”,而非 RESTful 参数绑定。
常见错误现象是把 app.Get("/api/*", handler) 当作“匹配所有子路径”,结果发现 /api/v1/users 能命中,但 /api/v1 不能——这是因为 * 只匹配**非空路径段**,且必须紧跟在 / 后面;/api/* 实际等价于 /api/.+,不匹配 /api/ 本身。
-
/foo/*→ 匹配/foo/bar、/foo/bar/baz,不匹配/foo/ -
/foo/*→ 不匹配/foobaz(*不是 glob 式模糊匹配) - 若需匹配空后缀,显式加一条
/foo路由 - 通配符捕获的内容可通过
c.Params("*")获取,返回的是完整子路径字符串(不含开头/)
用 app.All() 或正则实现更灵活的通配需求
如果只是想“兜底所有未匹配路由”,别硬套 *,直接用 app.All("*", handler) 更可靠。它会响应所有 HTTP 方法(GET/POST/PUT 等)下任意路径,适合做 404 处理或代理中转。
需要精确控制匹配逻辑时,Fiber 允许传入正则表达式作为路径:
app.Get("/user/(?<id>\d+)", func(c *fiber.Ctx) error {
id := c.Params("id") // 提取命名组
return c.SendString("User ID: " + id)
})
</id>
注意点:
- 正则路径必须用原始字符串(
`包裹),避免 Go 字符串转义干扰 - 命名捕获组语法为
(?<name>...)</name>,不是(?P<name>...)</name> - 未命名组(如
(d+))也能用c.Params("0")、c.Params("1")按序访问 - 正则匹配性能略低于静态路径,高频路由慎用复杂正则
c.Params("*") 返回值生命周期很短
通配符捕获的值(如 c.Params("*"))和所有 c.Params() 结果一样,底层指向复用的内存缓冲区。一旦 handler 返回,这块内存可能被下次请求覆盖。
如果你打算把通配路径存起来异步处理、传给 goroutine 或塞进 map,必须立刻拷贝:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
app.Get("/static/*", func(c *fiber.Ctx) error {
path := c.Params("*") // 危险:只在当前 handler 有效
safePath := string(append([]byte(nil), path...)) // 安全拷贝
go processStatic(safePath) // 可以放心传出去
return nil
})
或者启用全局不可变模式(牺牲一点性能):
app := fiber.New(fiber.Config{Immutable: true})
这样所有 c.Params() 返回的字符串都自动深拷贝,不用手动处理,但要注意:Fiber v3 已默认启用 Immutable: true,v2 需显式配置。
为什么 /api/* 有时不生效?检查路由注册顺序
Fiber 是线性匹配,路由注册顺序直接影响结果。比如:
app.Get("/api/users", handlerA)
app.Get("/api/*", handlerB)
这时 /api/users 会走 handlerA;但如果把 /api/* 写在前面:
app.Get("/api/*", handlerB)
app.Get("/api/users", handlerA) // 永远不会触发
因为 /api/* 已经匹配了所有 /api/xxx,后续同级路由不再检查。真实项目里容易忽略这点,尤其加中间件或分组路由时。
建议:静态路由放前,通配路由放后;用 app.Group() 隔离不同层级的通配逻辑,避免污染主路由栈。










