參考博客
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) } }

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) } }
在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", }) }
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) } }
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", }) }
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) } }
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 }
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()) } }
~~~