zoukankan      html  css  js  c++  java
  • gin项目的路由拆分与注册

    参考博客

    https://www.liwenzhou.com/posts/Go/gin_routes_registry/

    基本的路由注册

    func TestRouterGroup(t *testing.T){
        // 定义默认引擎
        r := gin.Default()
    
        // 路由组 userGroup
        userGroup := r.Group("/user")
        {
            // /user/index
            userGroup.GET("/index",func(c *gin.Context){
                c.JSON(http.StatusOK,gin.H{
                    "msg":"user.index",
                })
            })
            // /user/login
            userGroup.GET("/login",func(c *gin.Context){
                c.JSON(http.StatusOK,gin.H{
                    "msg":"user.login",
                })
            })
        }
    
        // 路由组 shopGroup
        shopGroup := r.Group("/shop")
        {
            // shop/index
            shopGroup.GET("/index",func(c *gin.Context){
                c.JSON(http.StatusOK,gin.H{
                    "msg":"shop.index",
                })
            })
            // shop/login
            shopGroup.GET("/login",func(c *gin.Context){
                c.JSON(http.StatusOK,gin.H{
                    "msg":"shop.login",
                })
            })
        }
    
        // 启动服务
        r.Run("127.0.0.1:9900")
    }
    基本的路由注册

    将路由拆分成单独的包

    当项目的规模增大后就不太适合继续在项目的main.go文件中去实现路由注册相关逻辑了,我们会倾向于把路由部分的代码都拆分出来,形成一个单独的文件或包:

    我们在routers.go文件中定义并注册路由信息:

    目录结构

    在 routers/r1.go 中加入视图函数与生成引擎的代码:

    package routers
    
    import (
        "github.com/gin-gonic/gin"
        "net/http"
    )
    
    // 视图函数
    func helloHandler(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "status": "OK",
            "msg":    "hello Handler!",
        })
    }
    
    // 初始化路由的函数 注意首字母大写
    func SetupRouter() *gin.Engine {
        // 默认引擎
        r := gin.Default()
        // 注册路由
        r.GET("/hello", helloHandler)
    
        return r
    }

    在 main.go 中引入并启动服务即可:

    package main
    
    import (
        "fmt"
        "ginRouters/routers"
    )
    
    func main() {
        router := routers.SetupRouter()
    
        if err := router.Run("127.0.0.1:9000"); err != nil{
            fmt.Println("启动服务失败!err>>> ",err.Error())
        }
    }

    路由拆分成多个文件

    当我们的业务规模继续膨胀,单独的一个routers文件或包已经满足不了我们的需求了,

    因为我们把所有的路由注册都写在一个SetupRouter函数中的话就会太复杂了。

    我们可以分开定义多个路由文件:

     

    在 routers/r1.go 与 routers/r2.go 中分别写上加载路由的逻辑:(写成路由组的形式)

    package routers
    
    import (
        "github.com/gin-gonic/gin"
        "net/http"
    )
    
    // r1的视图函数
    func helloHandler(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "status": "OK",
            "msg":    "hello Handler!",
        })
    }
    
    func postHandler(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "status": "OK",
            "msg":    "r1.postHandler",
        })
    }
    
    // 添加一个load函数,将路由注册进去,这里可以放一个路由组
    func LoadR1(e *gin.Engine) {
        r1Group := e.Group("/r1")
        {
            // 注册2条路由
            r1Group.GET("/hello", helloHandler)
            r1Group.POST("/post", postHandler)
        }
    }
    routers/r1.go
    package routers
    
    import (
        "github.com/gin-gonic/gin"
        "net/http"
    )
    
    //r2的视图函数
    func indexHandler(c *gin.Context){
        c.JSON(http.StatusOK, gin.H{
            "message":"r2.indexHandler",
        })
    }
    
    func r2PostHandler(c *gin.Context){
        c.JSON(http.StatusOK, gin.H{
            "message":"r2.postHandler",
        })
    }
    
    // load函数,将路由组注册进去
    func LoadR2(e *gin.Engine) {
        r2Group := e.Group("/r2")
        {
            r2Group.GET("/index",indexHandler)
            r2Group.POST("/post",r2PostHandler)
        }
    }
    routers/r2.go

    在main.go中创建一个引擎,然后分别加载对应的路由即可:

    package main
    
    import (
        "fmt"
        "github.com/gin-gonic/gin"
        "ginRouters/routers"
    )
    
    func main() {
    
        // 创建一个默认引擎
        r := gin.Default()
    
        // 加载 r1 与 r2 的路由
        routers.LoadR1(r)
        routers.LoadR2(r)
    
        // 启动服务
        if err := r.Run("127.0.0.1:9003"); err != nil{
            fmt.Println("服务启动失败!err: ",err.Error())
        }
    }

    路由拆分到不同的APP

    有时候项目规模实在太大,那么我们就更倾向于把业务拆分的更详细一些,例如把不同的业务代码拆分成不同的APP。

    因此我们在项目目录下单独定义一个app目录,用来存放我们不同业务线的代码文件,这样就很容易进行横向扩展。

    大致目录结构如下:

    blog应用

    视图函数写在app/blog/handler.go中:

    package blog
    
    import (
        "github.com/gin-gonic/gin"
        "net/http"
    )
    
    // blog的视图函数
    func postHandler(c *gin.Context){
        c.JSON(http.StatusOK,gin.H{
            "msg":"blog.postHandler",
        })
    }
    
    func commentHandler(c *gin.Context){
        c.JSON(http.StatusOK, gin.H{
            "msg":"blog.commentHandler",
        })
    }
    handler.go

    router.go中注册路由组

    package blog
    
    import "github.com/gin-gonic/gin"
    
    // load blog的路由 写成路由组
    func LoadBlogRouters(e *gin.Engine) {
        blogGroup := e.Group("/blog")
        {
            blogGroup.POST("/post", postHandler)
            blogGroup.POST("/comment", commentHandler)
        }
    }
    router.go

    shop应用

    视图函数写在handler.go中:

    package shop
    
    import (
        "github.com/gin-gonic/gin"
        "net/http"
    )
    
    // shop的视图函数
    func goodsHandler(c *gin.Context){
        c.JSON(http.StatusOK,gin.H{
            "msg":"shop.goods",
        })
    }
    
    func checkHandler(c *gin.Context){
        c.JSON(http.StatusOK,gin.H{
            "msg":"shop.check",
        })
    }
    handler.go

    router.go中注册路由组

    package shop
    
    import "github.com/gin-gonic/gin"
    
    // load shop中的路由  写成路由组
    func LoadShopRouters(e *gin.Engine){
        shopGroup := e.Group("/shop")
        {
            shopGroup.POST("/goods", goodsHandler)
            shopGroup.POST("/check", checkHandler)
        }
    }
    router.go

    routers/routers.go中初始化所有应用的路由

    routers/routers.go中根据需要定义Include函数用来注册子app中定义的路由,InitRouters函数用来进行路由的初始化操作:

    package routers
    
    import (
        "github.com/gin-gonic/gin"
    )
    
    type Option func(engine *gin.Engine)
    
    var options []Option
    
    // 注册app的路由配置
    func Include(optObjs ...Option) {
        // 打散传参
        options = append(options, optObjs...)
    }
    
    // Init函数用来进行路由的初始化
    func InitRouters() *gin.Engine{
        // 默认引擎
        r := gin.Default()
    
        for _, opt := range options{
            // 注册路由
            opt(r)
        }
    
        return r
    }
    routers/routers.go

    main.go

    main.go中按如下方式先注册子app中的路由,然后再进行路由的初始化:

    package main
    
    import (
        "fmt"
        "ginRouters/routers"
        "ginRouters/app/blog"
        "ginRouters/app/shop"
    )
    
    
    func main() {
    
        // 加载多个APP的路由配置
        // 将对应的load方法传进去
        routers.Include(shop.LoadShopRouters, blog.LoadBlogRouters)
    
        // 初始化路由
        r := routers.InitRouters()
    
        // 启动服务
        if err := r.Run("127.0.0.1:9004"); err != nil{
            fmt.Println("err>>> ", err.Error())
        }
    }

    ~~~

  • 相关阅读:
    C++元编程和Boost编程库 (C++ Metaprogramming and Boost MPL )中部
    支持插件的消息中间件【msg broker with plugin】 知然 博客园
    sync date
    Rubular: a Ruby regular expression editor and tester
    当爬虫被拒绝时(Access Denied) 风中之炎 博客园
    quartz scheduler
    C++ 使用STL string 实现的split,trim,replace修订
    java脚本编程 语言、框架与模式
    C++标准转换运算符const_cast
    http://jsoneditoronline.org/
  • 原文地址:https://www.cnblogs.com/paulwhw/p/14103123.html
Copyright © 2011-2022 走看看