gin路由高级
路由分组
routes group是为了管理一些相同的URL
https://gin-gonic.com/zh-cn/docs/examples/grouping-routes/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package main import ( "fmt" "github.com/gin-gonic/gin" ) // gin的helloWorld func main() { // 1.创建路由 r := gin.Default() // 路由组1 ,处理GET请求 v1 := r.Group( "/v1" ) // {} 是书写规范,不写也可以 { v1.GET( "/login" , login) v1.GET( "submit" , submit) // /不写也可以 } v2 := r.Group( "/v2" ) v2.POST( "/login" , login) v2.POST( "/submit" , submit) r.Run( ":8000" ) } func login(c *gin.Context) { name := c.DefaultQuery( "name" , "lqz" ) c.String(200, fmt.Sprintf( "hello %s\n" , name)) } func submit(c *gin.Context) { name := c.DefaultQuery( "name" , "pyy" ) c.String(200, fmt.Sprintf( "hello %s\n" , name)) } |
测试
1 2 3 4 5 | get请求:127.0.0.1:8000/v1/login post请求:127.0.0.1:8000/v1/submit get请求:127.0.0.1:8000/v2/login post请求:127.0.0.1:8000/v2/submit |
路由拆分与注册
基本路由注册
适用于路由比较少的简单项目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | package main import ( "net/http" "github.com/gin-gonic/gin" ) func helloHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message" : "Hello world!" , }) } func main() { r := gin.Default() r.GET( "/hello" , helloHandler) r.Run() } |
路由拆分成单独文件或包
当项目的规模增大后就不太适合继续在项目的main.go
文件中去实现路由注册相关逻辑了,我们会倾向于把路由部分的代码都拆分出来,形成一个单独的文件或包
1.拆分到单独文件中(不使用分组)
目录结构
routers.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package main import ( "net/http" "github.com/gin-gonic/gin" ) func helloHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg" : "www.liuqingzheng.top" , }) } func testHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "status" :100, "msg" : "hello world" , }) } func initRouter() *gin.Engine { r := gin.Default() r.GET( "/hello" , helloHandler) r.GET( "/test" , testHandler) return r } |
main.go
1 2 3 4 5 6 7 8 9 10 | package main func main() { r := initRouter() r.Run() } //访问 //http://127.0.0.1:8080/test http: //127.0.0.1:8080/hello |
2.拆分到包中
目录结构
routers/routers.go
outers/routers.go
需要注意此时initRouter需要改成首字母大写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package routers import ( "net/http" "github.com/gin-gonic/gin" ) func helloHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg" : "www.liuqingzheng.top" , }) } func testHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "status" :100, "msg" : "hello world" , }) } func InitRouter() *gin.Engine { r := gin.Default() r.GET( "/hello" , helloHandler) r.GET( "/test" , testHandler) return r } |
main.go
1 2 3 4 5 6 7 8 | package main import "gin_test/routers" func main() { r := routers.InitRouter() r.Run() } |
3.路由拆分成多个文件
单独的一个routers
文件或包已经满足不了我们的需求了
目录结构
routers/goods.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package routers import ( "github.com/gin-gonic/gin" "net/http" ) func LoadGoodsRouters(r *gin.Engine) { good := r.Group( "/good" ) { good.GET( "/" , goodHandler) good.GET( "/goodlist" , goodlistHandler) good.GET( "/updategood" , updategoodHandler) } } func goodHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg" : "www.liuqingzheng.top" , }) } func goodlistHandler(c *gin.Context) { c.String(http.StatusOK, "goodlistHandler" ) } func updategoodHandler(c *gin.Context) { c.String(http.StatusOK, "updategoodHandler" ) } |
routers/order.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package routers import ( "github.com/gin-gonic/gin" "net/http" ) func LoadOrderRouters(r *gin.Engine) { order := r.Group( "/order" ) { order.GET( "/" , orderHandler) order.GET( "/orderlist" , orderlistHandler) order.GET( "/updateorder" , updateorderHandler) } } func orderHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg" : "www.liuqingzheng.top" , }) } func orderlistHandler(c *gin.Context) { c.String(http.StatusOK, "orderlistHandler" ) } func updateorderHandler(c *gin.Context) { c.String(http.StatusOK, "updateorderHandler" ) } |
routers/user.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package routers import ( "github.com/gin-gonic/gin" "net/http" ) func LoadUserRouters(r *gin.Engine) { user := r.Group( "/user" ) { user.GET( "/" , userHandler) user.GET( "/userlist" , userlistHandler) user.GET( "/updateuser" , updateuserHandler) } } func userHandler(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "msg" : "www.liuqingzheng.top" , }) } func userlistHandler(c *gin.Context) { c.String(http.StatusOK, "userlistHandler" ) } func updateuserHandler(c *gin.Context) { c.String(http.StatusOK, "updateuserHandler" ) } |
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package main import ( "gin_test/routers" "github.com/gin-gonic/gin" ) func main() { r := gin.Default() routers.LoadGoodsRouters(r) routers.LoadOrderRouters(r) routers.LoadUserRouters(r) r.Run() } |
4.路由拆分到不同的APP
有时候项目规模实在太大,那么我们就更倾向于把业务拆分的更详细一些,例如把不同的业务代码拆分成不同的APP。
因此我们在项目目录下单独定义一个app
目录,用来存放我们不同业务线的代码文件,这样就很容易进行横向扩展。大致目录结构如下:
app01/shop/handler.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package shop import ( "github.com/gin-gonic/gin" "net/http" ) func shopHandler(c *gin.Context) { c.String(http.StatusOK, "shopHandler" ) } func shopInfoHandler(c *gin.Context) { c.String(http.StatusOK, "shopInfoHandler" ) } |
app01/shop/router.go
1 2 3 4 5 6 7 8 | package shop import "github.com/gin-gonic/gin" func Routers(e *gin.Engine) { e.GET( "/shop" , shopHandler) e.GET( "/shopinfo" , shopInfoHandler) } |
app01/user/handler.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package user import ( "github.com/gin-gonic/gin" "net/http" ) func userHandler(c *gin.Context) { c.String(http.StatusOK, "userHandler" ) } func userInfoHandler(c *gin.Context) { c.String(http.StatusOK, "userInfoHandler" ) } |
app01/user/router.go
1 2 3 4 5 6 7 8 9 | package user import "github.com/gin-gonic/gin" func Routers(e *gin.Engine) { e.GET( "/user" , userHandler) e.GET( "/userinfo" , userInfoHandler) } |
routers/routers.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package routers import "github.com/gin-gonic/gin" type Option func (engine *gin.Engine) var options=[]Option{} //注册app的路由配置 func Include(opts ...Option) { options=append(options,opts...) } //初始化 func Init()*gin.Engine { r:=gin.New() for _,opt:= range options{ opt(r) } return r } |
main.go
1 2 3 4 5 6 7 8 9 10 11 12 13 | package main import ( "gin_test/app01/shop" "gin_test/app01/user" "gin_test/routers" ) func main() { routers.Include(shop.Routers,user.Routers) r:=routers.Init() r.Run() } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)