1. 程式人生 > 其它 >golang gin後端開發框架(三)

golang gin後端開發框架(三)

1. 路由組

在實際的專案開發中,均是模組化開發

同一模組內的功能介面,往往會有相同的介面字首,這種可以用路由組來進行分類處理。

比如下面這幾組介面:

註冊:http://localhost:8080/user/register
登陸:http://localhost:8080/user/login
使用者資訊:http://localhost:8080/user/info

 

gin框架可以使用路由組來實現對路由的分類

路由組是router.Group中的一個方法,對於請求進行分組

func main() {
	engine := gin.Default()

	// 註冊路由組
	routerGroup := engine.Group("/user")

	routerGroup.POST("/register", func(ctx *gin.Context) {})
	routerGroup.POST("/login", func(ctx *gin.Context) {})
	routerGroup.GET("/info", func(ctx *gin.Context) {})

	engine.Run()
}

 

2. 中介軟體

 在實際的業務開發中,一個完整的系統可能要包含鑑權認證、許可權管理、安全檢查、日誌記錄等多個維度的系統支援

鑑權認證、許可權管理、安全檢查等業務都是屬於全系統的業務,和具體的業務沒有直接關聯

因此在開發中,為了更好的梳理系統架構,可以將以上這些業務單獨抽離出來,以外掛化的方式進行對接

這種通用業務獨立開發並靈活配置使用的元件,稱之為中介軟體,其位於伺服器和實際業務處理程式之間

 

 

2.1 gin的中介軟體

在gin中,中介軟體的型別定義如下:

// HandlerFunc defines the handler used by gin middleware as return value
type HandlerFunc func(*Context)

HandlerFunc是一個函式型別,接收一個Context引數。用於編寫程式處理函式並返回HandleFunc型別,作為中介軟體定義

 

2.2 中介軟體Use用法

關於初始化gin engine的gin.Default()方法的實現中也使用了兩個中介軟體

// Default returns an Engine instance with the Logger and Recovery middleware already attached.
func Default() *Engine {
	debugPrintWARNINGDefault()
	engine := New()
	engine.Use(Logger(), Recovery())
	return engine
}

 

我們可以跳轉到Logger()中介軟體的定義,去看看實現一箇中間件的格式是什麼

// Logger instances a Logger middleware that will write the logs to gin.DefaultWriter.
// By default, gin.DefaultWriter = os.Stdout.
func Logger() HandlerFunc {
	return LoggerWithConfig(LoggerConfig{})
}

 

2.3 自定義中介軟體

根據上文關於中介軟體的描述中,我們可以自定義一個特殊需求的中介軟體,中介軟體型別是函式,有兩條標準:

  • func函式
  • 返回值型別為HandlerFunc

比如我們現在有一個需求,實現一箇中間件,其功能就是打印出請求的path和method:

// RequestInfos 實現一箇中間件
func RequestInfos() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		path := ctx.FullPath()
		method := ctx.Request.Method
		fmt.Println(path, method)
	}
}

  

使用或者註冊中介軟體時有兩種方式,一種是直接使用engine.Use(),那麼所有介面都會經過這個中介軟體處理

// 使用中介軟體,所有介面都經過這個中介軟體
engine.Use(RequestInfos())

  

或者為某一個處理註冊一箇中間件,那麼只有這一個請求會經過該中介軟體

engine.GET("/query", RequestInfos(), func(ctx *gin.Context) {
	ctx.JSON(http.StatusOK, map[string]interface{}{
		"code":    1,
		"message": ctx.FullPath(),
	})
})

 

2.4 context.Next函式

在上面自定義中介軟體RequestInfos()中,列印了請求的路徑和請求的method,接著去執行了正常的業務處理函式

如果我們想輸出業務處理的結果,就應該使用context.Next來實現

context.Next可以將中介軟體程式碼一分為二:

  • Next()之前的程式碼會在請求處理之前執行
  • 當中間件執行流遇到context.Next時,會中斷執行,轉而執行業務邏輯
  • 當業務邏輯執行完之後,再次回到Next函式處,繼續向下執行中介軟體邏輯,從而獲取業務執行之後的結果

 具體用法如下:

// RequestInfos 實現一箇中間件
func RequestInfos() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		path := ctx.FullPath()
		method := ctx.Request.Method
		fmt.Println(path, method)

		ctx.Next() // 在此處一分為二

		fmt.Println(ctx.Writer.Status())
	}
}