middleware中间件
golang的net/http设计的一大特点就是特别容易构建中间件。gin也提供了类似的中间件。需要注意的是中间件只对注册过的路由函数起作用。对于分组路由,嵌套使用中间件,可以限定中间件的作用范围。中间件分为全局中间件,单个路由中间件和群组中间件。
全局中间件
先定义一个中间件函数:
func
MiddleWare
()
gin.HandlerFunc
{
return
func(c *gin.Context) {
fmt.Println(
"before middleware"
)
c.Set(
"request"
,
"clinet_request"
)
c.Next()
fmt.Println(
"before middleware"
)
}
}
该函数很简单,只会给c上下文添加一个属性,并赋值。后面的路由处理器,可以根据被中间件装饰后提取其值。需要注意,虽然名为全局中间件,只要注册中间件的过程之前设置的路由,将不会受注册的中间件所影响。只有注册了中间件一下代码的路由函数规则,才会被中间件装饰。
router.Use(MiddleWare())
{
router.GET(
"/middleware"
, func(c *gin.Context) {
request := c.MustGet(
"request"
).(
string
)
req, _ := c.Get(
"request"
)
c.JSON(http.StatusOK, gin.H{
"middile_request"
: request,
"request"
: req,
})
})
}
使用router装饰中间件,然后在/middlerware即可读取request的值,注意在router.Use(MiddleWare())代码以上的路由函数,将不会有被中间件装饰的效果。
使用花括号包含被装饰的路由函数只是一个代码规范,即使没有被包含在内的路由函数,只要使用router进行路由,都等于被装饰了。想要区分权限范围,可以使用组返回的对象注册中间件。
☁ ~ curl http:
//127.0.0.1:8000/middleware
{
"middile_request"
:
"clinet_request"
,
"request"
:
"clinet_request"
}
如果没有注册就使用MustGet方法读取c的值将会抛错,可以使用Get方法取而代之。
上面的注册装饰方式,会让所有下面所写的代码都默认使用了router的注册过的中间件。
单个路由中间件
当然,gin也提供了针对指定的路由函数进行注册。
router.GET(
"/before"
, MiddleWare(), func(c *gin.Context) {
request := c.MustGet(
"request"
).(
string
)
c.JSON(http.StatusOK, gin.H{
"middile_request"
: request,
})
})
把上述代码写在 router.Use(Middleware())之前,同样也能看见/before被装饰了中间件。
群组中间件
群组的中间件也类似,只要在对于的群组路由上注册中间件函数即可:
authorized := router.Group(
"/"
, MyMiddelware())
// 或者这样用:
authorized := router.Group(
"/"
)
authorized.
Use
(MyMiddelware())
{
authorized.POST(
"/login"
, loginEndpoint)
}
群组可以嵌套,因为中间件也可以根据群组的嵌套规则嵌套。