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())
    }
}

~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM