Gin中router.Group()是唯一原生模块隔离机制,通过路径前缀(如/user、/order)划分业务模块,组内用相对路径注册路由,并支持中间件局部叠加;必须显式调用各模块初始化函数统一注册,禁用init()自动加载。

gin.Default() 创建的路由实例本身不支持自动拆分模块,必须手动组织结构。直接把所有 router.GET、router.POST 塞进一个文件,项目超过 20 个接口后就难定位、易冲突、没法并行开发。
如何用 router.Group() 划分业务模块
router.Group() 是 Gin 提供的唯一原生模块隔离机制,它不新建引擎,只生成子路由上下文,共享父级中间件但可叠加新中间件。
- 每个模块对应一个独立的
router.Group()调用,路径前缀要体现业务语义,比如user、order、admin,避免用v1这类纯版本号作一级前缀(版本应嵌套在模块内,如/api/v1/user) - 组内注册路由时,路径写相对路径(如
"/list"),不是全路径(不要写"/api/v1/user/list") - 同一模块的 handler 函数建议集中放在
api/controller/xxx.go,别散落在各处
userGroup := r.Group("/api/v1/user")
{
userGroup.GET("/list", user.ListHandler)
userGroup.GET("/:id", user.DetailHandler)
userGroup.POST("", user.CreateHandler)
}多个模块路由如何统一注册到主引擎
Gin 没有内置“自动扫描路由文件”机制,必须显式调用每个模块的初始化函数。推荐在api/router/router.go 中定义一个 InitRouter() 函数,接收 *gin.Engine 参数,再逐个调用各模块的注册逻辑。
- 不要用全局变量缓存
*gin.Engine,防止测试时状态污染 - 模块注册函数命名保持一致,如
UserRouterInit(r <em>gin.Engine)</em>、OrderRouterInit(r gin.Engine) - 所有中间件应在主
router.go中统一挂载,模块内只处理业务路由,不重复加Use()
示例结构:
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
// api/router/router.go
func InitRouter(r *gin.Engine) {
r.Use(gin.Recovery(), loggerMiddleware())
UserRouterInit(r)
OrderRouterInit(r)
AdminRouterInit(r)
}
<p>// api/router/user.go
func UserRouterInit(r *gin.Engine) {
group := r.Group("/api/v1/user")
group.GET("/list", controller.UserList)
group.POST("", controller.UserCreate)
}为什么不能把模块路由写在 init() 函数里
init() 是包加载时自动执行的,它无法接收 *gin.Engine 实例,也无法控制执行顺序。一旦某个模块的 init() 尝试操作未初始化的全局路由变量,就会 panic。
-
init()适合做常量预热、配置加载,不适合做依赖注入类操作 - 如果强行在
init()里调用gin.Default(),会导致多个包各自创建独立引擎,最终只有最后一个生效,前面的路由全部丢失 - 测试时无法替换
*gin.Engine实例(比如注入 mock router),单元测试会失败
中间件作用域容易被忽略的细节
router.Use() 对后续所有路由生效,但 group.Use() 只对当前组及其子组生效。常见错误是把鉴权中间件挂错位置:
- 全局鉴权(如 JWT 校验)应放在主
router.go的r.Use(),而不是某个 group 里 - 某模块专属中间件(如订单导出限流)必须挂在对应
group.Use(),否则会影响用户模块等其他路由 -
group.Use()必须在group.GET()等注册之前调用,顺序颠倒会导致中间件不生效
最常踩的坑:在 group 内部重复调用 r.Use(),这实际是在主引擎上加中间件,污染了全局行为。


















