Gin 框架怎么使用中間件?
1.介紹
在 Gin 框架中,HTTP 請求可以由一系列中間件和最終操作來處理。
本文我們介紹怎么使用中間件。
2.使用中間件
Gin 框架使用中間件,分為全局中間件、路由中間件、路由組中間件。
示例代碼:
func main() {
// 新建一個沒有任何默認中間件的路由
r := gin.New()
// 全局中間件
r.Use(gin.Logger())
r.Use(gin.Recovery())
// 路由中間件
r.GET("/benchmark", MyBenchLogger(), benchEndpoint))
// 路由組中間件
authorized := r.Group("/")
authorized.Use(AuthRequired())
{
authorized.POST("/login", loginEndpoint)
authorized.POST("/submit", submitEndpoint)
authorized.POST("/read", readEndpoint)
// 嵌套路由組
testing := authorized.Group("testing")
testing.GET("/analytics", analyticsEndpoint)
}
r.Run(":8080")
}
閱讀上面這段代碼,我們可以發現,Gin 框架使用 Use 方法,使用中間件,包含默認中間件和自定義中間件。
3.自定義中間件
Gin 框架除了使用默認中間件,還可以自定義中間件。
我們先閱讀默認中間件 Recovery 的源碼。
// Recovery returns a middleware that recovers from any panics and writes a 500 if there was one.
func Recovery() HandlerFunc {
return RecoveryWithWriter(DefaultErrorWriter)
}
// RecoveryWithWriter returns a middleware for a given writer that recovers from any panics and writes a 500 if there was one.
func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc {
if len(recovery) > 0 {
return CustomRecoveryWithWriter(out, recovery[0])
}
return CustomRecoveryWithWriter(out, defaultHandleRecovery)
}
閱讀默認中間件 Recovery 的源碼,我們可以發現,Gin 框架中間件,就是一個有 HandlerFunc 類型返回值的函數。
我們閱讀 CustomRecoveryWithWriter 函數的源碼,可以發現 c.Next() 方法,該方法只在中間件內部使用。
它的作用是,當代碼執行到 c.Next() 方法,會先調用后續的處理函數,最后再執行完當前函數的代碼。
自定義中間件:
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{
"ping": "pong",
})
}, MyMiddleware1(), MyMiddleware2())
err := r.Run(":8080")
if err != nil {
return
}
}
func MyMiddleware1() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("abc")
defer func() {
fmt.Println("def")
}()
c.Next()
fmt.Println("ghi")
}
}
func MyMiddleware2() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println("111")
defer func() {
fmt.Println("222")
}()
c.Next()
fmt.Println("333")
}
}
輸出結果:
curl -s -X GET http://127.0.0.1:8080 | jq
{
"ping": "pong"
}
abc
111
333
222
ghi
def
閱讀上面這段代碼,我們定義三個中間件函數,其中每個中間件函數中都使用 c.Next() 方法。
通過輸出結果,我們可以發現,代碼執行順序是,先正序分別執行三個中間件的 c.Next() 方法之前的代碼。
然后,再倒序分別執行三個中間件 c.Next() 方法之后的代碼。
4.總結
本文我們介紹 Gin 框架怎么使用中間件,包括全局中間件、路由中間件、路由組中間件。
我們還介紹了怎么自定義中間件,以及中間件使用的 c.Next() 方法的執行順序。