Gin 框架怎么使用中間件?
1.介紹
在 Gin 框架中,HTTP 請(qǐng)求可以由一系列中間件和最終操作來處理。
本文我們介紹怎么使用中間件。
2.使用中間件
Gin 框架使用中間件,分為全局中間件、路由中間件、路由組中間件。
示例代碼:
func main() {
// 新建一個(gè)沒有任何默認(rèn)中間件的路由
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")
}
閱讀上面這段代碼,我們可以發(fā)現(xiàn),Gin 框架使用 Use 方法,使用中間件,包含默認(rèn)中間件和自定義中間件。
3.自定義中間件
Gin 框架除了使用默認(rèn)中間件,還可以自定義中間件。
我們先閱讀默認(rèn)中間件 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)
}
閱讀默認(rèn)中間件 Recovery 的源碼,我們可以發(fā)現(xiàn),Gin 框架中間件,就是一個(gè)有 HandlerFunc 類型返回值的函數(shù)。
我們閱讀 CustomRecoveryWithWriter 函數(shù)的源碼,可以發(fā)現(xiàn) c.Next() 方法,該方法只在中間件內(nèi)部使用。
它的作用是,當(dāng)代碼執(zhí)行到 c.Next() 方法,會(huì)先調(diào)用后續(xù)的處理函數(shù),最后再執(zhí)行完當(dāng)前函數(shù)的代碼。
自定義中間件:
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")
}
}
輸出結(jié)果:
curl -s -X GET http://127.0.0.1:8080 | jq
{
"ping": "pong"
}
abc
111
333
222
ghi
def
閱讀上面這段代碼,我們定義三個(gè)中間件函數(shù),其中每個(gè)中間件函數(shù)中都使用 c.Next() 方法。
通過輸出結(jié)果,我們可以發(fā)現(xiàn),代碼執(zhí)行順序是,先正序分別執(zhí)行三個(gè)中間件的 c.Next() 方法之前的代碼。
然后,再倒序分別執(zhí)行三個(gè)中間件 c.Next() 方法之后的代碼。
4.總結(jié)
本文我們介紹 Gin 框架怎么使用中間件,包括全局中間件、路由中間件、路由組中間件。
我們還介紹了怎么自定義中間件,以及中間件使用的 c.Next() 方法的執(zhí)行順序。