路由组前缀必须以/开头,如r.Group("/api"),否则路径注册错误导致404;嵌套时前缀叠加而非覆盖,中间件与前缀正交,变量路由语法不变。

路由组前缀必须以 / 开头,不能省略或重复
直接写 r.Group("api") 是错的,实际注册的路径会变成 api/users 而不是预期的 /api/users。Gin 不会自动补前导斜杠,也不做字符串拼接——它把传入的字符串原样作为子树根路径。正确写法是显式带上开头的 /:r.Group("/api")。
常见错误现象:访问 /api/users 返回 404,但 /users 却能命中;这是因为前缀缺失导致路由注册到了根层级下,和你直觉中的“分组”完全脱节。
-
r.Group("/api/v1")→ 实际匹配/api/v1/xxx -
r.Group("//api")或r.Group("/api/")→ 可能触发意外行为(如双斜杠被某些代理规范化,或结尾斜杠影响客户端缓存) - 空字符串
r.Group("")合法,但等价于根组,无实际分组意义,不推荐
嵌套路由组的前缀是叠加的,不是覆盖的
子组前缀会在父组基础上追加,不是替换。比如 v2 := r.Group("/v2") 下再写 admin := v2.Group("/admin"),最终路径是 /v2/admin/dashboard,而不是 /admin/dashboard。这点容易和中间件继承混淆——前缀叠加是确定的,但中间件不会自动继承,必须显式传参。
使用场景:API 版本 + 模块划分(如 /v2/auth、/v2/payment),或前后端分离时为管理后台统一加 /admin 前缀。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 父组
r.Group("/v2")+ 子组.Group("/auth")→ 完整路径/v2/auth/login - 父组
r.Group("/v2")+ 子组.Group("auth")(缺/)→ 注册为/v2auth/login,明显错误 - 嵌套超过两层极少必要,可读性会下降,建议用命名变量拆分(如
v2Auth := v2.Group("/auth"))
带中间件的路由组,前缀和中间件是正交的两个参数
r.Group("/admin", authMiddleware) 这种写法里,/admin 是路径前缀,authMiddleware 是中间件链,二者互不影响。前缀不提供任何权限控制能力,校验逻辑必须在中间件内部完成,并调用 c.Abort() 阻断后续 handler 执行。
性能影响:中间件在每次请求进入该组路由时都会执行,与路径前缀长度无关;但若中间件本身做了耗时操作(如 DB 查询、JWT 解析),应考虑缓存或提前拒绝。
- 错误认知:“加了
/admin前缀就等于有权限” → 实际上没中间件,任何人都能访问 - 正确姿势:中间件里检查 token 或 session,失败时
c.AbortWithStatusJSON(401, ...) - 多个中间件按顺序传入:
r.Group("/api", jwtAuth, rateLimit, logger)
变量路由(:id、*filepath)在分组内写法不变
路由组不改变参数化路径的语法。你在 api := r.Group("/api") 里写 api.GET("/user/:id", handler),完整路径就是 /api/user/123,:id 依然通过 c.Param("id") 获取。
容易踩的坑是误以为分组会“接管”变量作用域——其实变量只在当前注册的路径片段生效,和分组层级无关;不同分组里用同名 :id 也不会冲突。
-
api.GET("/post/:id", postHandler)→c.Param("id")取到的是 URL 中/post/后面的部分 -
v2.Group("/v2").GET("/file/*filepath", fileHandler)→c.Param("filepath")包含开头的/,需手动裁剪 - 通配符
*和参数:不能混用在同一段路径中,例如/user/:id/profile/*rest是非法的
Group 本质是构造 Radix Tree 的子树节点,不是字符串操作。一旦前缀写错,路由就注册到了错误的树分支上,debug 时看不到报错,只有 404——这是最隐蔽也最容易忽略的一环。


















