在 Gin 框架中,真正支撑路由能力的不是gin.Engine,而是gin.RouterGroup。
gin.Engine本质上是嵌入了RouterGroup的增强结构(type Engine struct { *RouterGroup ... }),因此你调用r.GET()、r.Group()时,实际上是在操作一个RouterGroup实例。
RouterGroup是 Gin 的核心抽象,它提供了:
- 路径前缀管理(自动拼接)
- 中间件作用域隔离
- 嵌套分组能力
- 统一的方法注册接口(GET/POST/Use/Static 等)
理解RouterGroup的工作方式,是掌握 Gin 架构设计的关键
HTTP 方法路由
// 所有 HTTP 方法GET(pathstring,handlers...HandlerFunc)IRoutesPOST(pathstring,handlers...HandlerFunc)IRoutesPUT(pathstring,handlers...HandlerFunc)IRoutesDELETE(pathstring,handlers...HandlerFunc)IRoutesPATCH(pathstring,handlers...HandlerFunc)IRoutesHEAD(pathstring,handlers...HandlerFunc)IRoutesOPTIONS(pathstring,handlers...HandlerFunc)IRoutesANY(pathstring,handlers...HandlerFunc)IRoutes// 自定义方法Handle(httpMethod,relativePathstring,handlers...HandlerFunc)IRoutes中间件管理
// 添加中间件Use(middleware...HandlerFunc)IRoutes分组创建
// 创建子分组Group(componentstring,handlers...HandlerFunc)*RouterGroup静态文件服务
// 静态文件StaticFile(relativePath,filepathstring)IRoutesStatic(relativePath,rootstring)IRoutesStaticFS(relativePathstring,fs http.FileSystem)IRoutes路径组合规则
// 基础路径组合规则r:=gin.Default()api:=r.Group("/api")// basePath: "/api"v1:=api.Group("/v1")// basePath: "/api/v1"users:=v1.Group("/users")// basePath: "/api/v1/users"// 最终路由:// users.GET("/profile") → 实际路径: /api/v1/users/profile// users.POST("/create") → 实际路径: /api/v1/users/create基础用法
funcmain(){r:=gin.Default()// Engine 本身就是一个 RouterGroupr.GET("/",handler)// r 是 *RouterGroup// 创建分组api:=r.Group("/api")// 返回 *RouterGroupapi.GET("/users",handler)api.POST("/users",handler)}分组嵌套
funcmain(){r:=gin.Default()// 一级分组api:=r.Group("/api"){api.GET("/users",handler1)api.POST("/users",handler2)// 二级分组v1:=api.Group("/v1"){v1.GET("/users",handler3)v1.POST("/users",handler4)}v2:=api.Group("/v2"){v2.GET("/users",handler5)}}}中间件分组
funcmain(){r:=gin.Default()// 公共路由组(无中间件)public:=r.Group("/public"){public.GET("/info",handler1)}// 受保护路由组(带认证中间件)protected:=r.Group("/api")protected.Use(AuthMiddleware())// 该组所有路由都使用认证中间件{protected.GET("/profile",handler2)protected.POST("/posts",handler3)// 在分组内再创建子分组admin:=protected.Group("/admin")admin.Use(AdminMiddleware())// 管理员中间件{admin.GET("/dashboard",handler4)admin.DELETE("/users/:id",handler5)}}}完整示例
packagemainimport("github.com/gin-gonic/gin""net/http")funcAuthMiddleware()gin.HandlerFunc{returnfunc(c*gin.Context){// 简单认证逻辑token:=c.GetHeader("Authorization")iftoken==""{c.JSON(401,gin.H{"error":"Unauthorized"})c.Abort()return}c.Next()}}funcAdminMiddleware()gin.HandlerFunc{returnfunc(c*gin.Context){// 简单管理员验证role:=c.GetHeader("Role")ifrole!="admin"{c.JSON(403,gin.H{"error":"Forbidden"})c.Abort()return}c.Next()}}funcmain(){r:=gin.Default()// 根分组(Engine 本身)r.GET("/",func(c*gin.Context){c.JSON(200,gin.H{"message":"Root path"})})// API 分组api:=r.Group("/api"){api.GET("/health",func(c*gin.Context){c.JSON(200,gin.H{"status":"ok"})})// 用户相关接口users:=api.Group("/users")users.Use(AuthMiddleware())// 用户接口需要认证{users.GET("/",func(c*gin.Context){c.JSON(200,gin.H{"users":[]string{"user1","user2"}})})users.GET("/:id",func(c*gin.Context){id:=c.Param("id")c.JSON(200,gin.H{"id":id,"name":"John"})})users.POST("/",func(c*gin.Context){c.JSON(201,gin.H{"message":"User created"})})}// 管理员接口admin:=api.Group("/admin")admin.Use(AuthMiddleware(),AdminMiddleware())// 需要认证+管理员权限{admin.GET("/dashboard",func(c*gin.Context){c.JSON(200,gin.H{"message":"Admin dashboard"})})admin.GET("/users",func(c*gin.Context){c.JSON(200,gin.H{"message":"Admin users list"})})}}// 静态文件static:=r.Group("/static")static.Static("/files","./files")// 静态文件服务r.Run()}