fiber 默认 strictrouting=true,/users 和 /users/ 是不同路由,需显式注册或重定向;参数读取来源严格分离:c.params() 仅路径占位符、c.queryparam() 仅 query string、c.bodyparser() 仅 json body;app.use() 前缀匹配要求精确或后跟/;禁用 fiber.default(),启用 casesensitive 和 strictrouting。

直接用 app.Get()、app.Post() 注册带前导斜杠的路径,别碰 fiber.Default(),也别指望关 StrictRouting 来“修 404”——那只会让路由逻辑更难预测。
为什么 /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 集合是否全用无尾斜杠路径
ctx.Params()、ctx.QueryParam()、ctx.BodyParser() 别混用
三者读取来源完全不同,参数名一样也不互通:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
-
c.Params("id")只从路径占位符提取,比如app.Get("/user/:id", h)匹配/user/123后的"123" -
c.QueryParam("q")只读?q=go这类 query string,对路径或 body 无效 -
c.BodyParser(&v)是解析 JSON body 的正解;c.FormValue("name")仅适用于application/x-www-form-urlencoded - URL 是
/user/123?format=json,那么c.Params("id") == "123",c.QueryParam("format") == "json",两者互不干扰
用 app.Use() 挂载中间件时,前缀匹配有边界要求
app.Use() 不是“包含子串就匹配”,而是精确匹配前缀或前缀后紧跟 /:
-
app.Use("/api", middleware)→ 匹配/api、/api/users、/api/v1/health -
app.Use("/api", middleware)→ 不匹配/apixxx或/api123(后面不是/或路径结束) - 它对所有 HTTP 方法生效(GET/POST/PUT/DELETE 等),底层会把该路由复制到每个方法栈
- 若要挂载子应用,直接
app.Use("/admin", adminApp),adminApp自带完整路由表即可
别用 fiber.Default() 上线,ctx.Next() 不是“继续往下走”
fiber.Default() 自带 Logger、Recover、RequestID,上线等于裸奔敏感头、拖慢 TTFB 0.3–0.8ms、压垮 I/O。
- 起点必须是
app := fiber.New(&fiber.Config{CaseSensitive: true, StrictRouting: true}),再按需加中间件 -
c.Next()是交还控制权给调度器,是否执行后续 handler,取决于当前 handler 是否已写响应体 - 权限中间件里写了
c.Status(401).Send("unauthorized"),再调c.Next()就没意义了——响应已发出,链路终止 - 拒绝就直接
return;放行才调c.Next()
最易被忽略的是:路由设计和参数读取是强契约行为,不是靠试错能调通的。写 app.Get("/user/:id", h) 就得确保请求路径是 /user/123,而不是 /user?id=123;读参数前先确认来源,比加日志更省时间。










