1. 程式人生 > 實用技巧 >gin框架路由拆分與註冊

gin框架路由拆分與註冊

轉自

gin框架路由拆分與註冊

基本的路由註冊

下面最基礎的gin路由註冊方式,適用於路由條目比較少的簡單專案或者專案demo。

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func helloHandler(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"message": "Hello q1mi!",
	})
}

func main() {
	r := gin.Default()
	r.GET("/hello", helloHandler)
	if err := r.Run(); err != nil {
		fmt.Println("startup service failed, err:%v\n", err)
	}
}

  

路由拆分成單獨檔案或包

當專案的規模增大後就不太適合繼續在專案的main.go檔案中去實現路由註冊相關邏輯了,我們會傾向於把路由部分的程式碼都拆分出來,形成一個單獨的檔案或包:

我們在routers.go檔案中定義並註冊路由資訊:

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func helloHandler(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"message": "Hello q1mi!",
	})
}

func setupRouter() *gin.Engine {
	r := gin.Default()
	r.GET("/hello", helloHandler)
	return r
}

  

此時main.go中呼叫上面定義好的setupRouter函式:

func main() {
	r := setupRouter()
	if err := r.Run(); err != nil {
		fmt.Println("startup service failed, err:%v\n", err)
	}
}

  

此時的目錄結構:

gin_demo
├── go.mod
├── go.sum
├── main.go
└── routers.go

把路由部分的程式碼單獨拆分成包的話也是可以的,拆分後的目錄結構如下:

gin_demo
├── go.mod
├── go.sum
├── main.go
└── routers
    └── routers.go

routers/routers.go需要注意此時setupRouter需要改成首字母大寫:

package routers

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func helloHandler(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"message": "Hello q1mi!",
	})
}

// SetupRouter 配置路由資訊
func SetupRouter() *gin.Engine {
	r := gin.Default()
	r.GET("/hello", helloHandler)
	return r
}

  

main.go檔案內容如下:

package main

import (
	"fmt"
	"gin_demo/routers"
)

func main() {
	r := routers.SetupRouter()
	if err := r.Run(); err != nil {
		fmt.Println("startup service failed, err:%v\n", err)
	}
}

  

路由拆分成多個檔案

當我們的業務規模繼續膨脹,單獨的一個routers檔案或包已經滿足不了我們的需求了,

func SetupRouter() *gin.Engine {
	r := gin.Default()
	r.GET("/hello", helloHandler)
  r.GET("/xx1", xxHandler1)
  ...
  r.GET("/xx30", xxHandler30)
	return r
}

  

因為我們把所有的路由註冊都寫在一個SetupRouter函式中的話就會太複雜了。

我們可以分開定義多個路由檔案,例如:

gin_demo
├── go.mod
├── go.sum
├── main.go
└── routers
    ├── blog.go
    └── shop.go

routers/shop.go中新增一個LoadShop的函式,將shop相關的路由註冊到指定的路由器:

func LoadShop(e *gin.Engine)  {
	e.GET("/hello", helloHandler)
  e.GET("/goods", goodsHandler)
  e.GET("/checkout", checkoutHandler)
  ...
}

  

routers/blog.go中新增一個`LoadBlog的函式,將blog相關的路由註冊到指定的路由器:

func LoadBlog(e *gin.Engine) {
	e.GET("/post", postHandler)
  e.GET("/comment", commentHandler)
  ...
}

  

在main函式中實現最終的註冊邏輯如下:

func main() {
	r := gin.Default()
	routers.LoadBlog(r)
	routers.LoadShop(r)
	if err := r.Run(); err != nil {
		fmt.Println("startup service failed, err:%v\n", err)
	}
}

  

路由拆分到不同的APP

有時候專案規模實在太大,那麼我們就更傾向於把業務拆分的更詳細一些,例如把不同的業務程式碼拆分成不同的APP。

因此我們在專案目錄下單獨定義一個app目錄,用來存放我們不同業務線的程式碼檔案,這樣就很容易進行橫向擴充套件。大致目錄結構如下:

gin_demo
├── app
│   ├── blog
│   │   ├── handler.go
│   │   └── router.go
│   └── shop
│       ├── handler.go
│       └── router.go
├── go.mod
├── go.sum
├── main.go
└── routers
    └── routers.go

其中app/blog/router.go用來定義post相關路由資訊,具體內容如下:

func Routers(e *gin.Engine) {
	e.GET("/post", postHandler)
	e.GET("/comment", commentHandler)
}

  

app/shop/router.go用來定義shop相關路由資訊,具體內容如下:

func Routers(e *gin.Engine) {
	e.GET("/goods", goodsHandler)
	e.GET("/checkout", checkoutHandler)
}

  

routers/routers.go中根據需要定義Include函式用來註冊子app中定義的路由,Init函式用來進行路由的初始化操作:

type Option func(*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中按如下方式先註冊子app中的路由,然後再進行路由的初始化:

func main() {
	// 載入多個APP的路由配置
	routers.Include(shop.Routers, blog.Routers)
	// 初始化路由
	r := routers.Init()
	if err := r.Run(); err != nil {
		fmt.Println("startup service failed, err:%v\n", err)
	}
}

  

總結

gin框架是一個非常容易擴充套件的web框架,本文是我在日常編碼中總結的一點點經驗,因為世界上不可能有完全相同的專案,每個人也都有自己的程式設計習慣,關於gin框架路由註冊的方式我就在此拋磚引玉了。