「这是我参与2022首次更文挑战的第17天,活动详情查看:2022首次更文挑战」
前言
gin框架里的中间件分为全局中间件,局部中间件。那么什么是中间件?中间件是为应用提供通用服务和功能的软件。数据管理、应用服务、消息传递、身份验证和 API 管理通常都要通过中间件。在gin框架里,就是我们的所有API接口都要经过我们的中间件,我们可以在中间件做一些拦截处理。
全局中间件
这个是在服务启动就开始注册,全局意味着所有API接口都会经过这里。Gin的中间件是通过Use方法设置的,它接收一个可变参数,所以我们同时可以设置多个中间件。
首先定义如下
// 1.创建路由r := gin.Default() //默认带Logger(), Recovery()这两个内置中间件
r:= gin.New() //不带任何中间件
// 注册中间件 r.Use(MiddleWare())
r.Use(MiddleWare2())
注意的是
gin.Default()默认使用了Logger和Recovery中间件,其中:Logger中间件将日志写入gin.DefaultWriter,即使配置了GIN_MODE=release。Recovery中间件会recover任何panic。如果有panic的话,会写入500响应码。如果不想使用上面两个默认的中间件,可以使用gin.New()新建一个没有任何默认中间件的路由。
中间件代码
// 定义中间
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
fmt.Println("中间件开始执行了")
// 设置变量到Context的key中,可以通过Get()取
c.Set("request", "这是中间件设置的值")
status := c.Writer.Status()
fmt.Println("中间件执行完毕", status) t2 := time.Since(t)
fmt.Println("time:", t2)
}
}
然后启动我们的服务,访问任意一个接口可以看到输出如下
这是请求先到了中间件,然后在到我们的API接口。在中间件里可以设置变量到Context的key中,然后在我们的API接口取值。
r.GET("/", func(c *gin.Context) {
// 取值
req, _ := c.Get("request")
fmt.Println("request:", req)
// 页面接收
c.JSON(200, gin.H{"request": req})
})
这时候在访问就可以看到中间件设置的值是
next方法是在中间件里面使用,这个是执行后续中间件请求处理的意思(含没有执行的中间件和我们定义的GET方法处理,如果连续注册几个中间件则会是按照顺序先进后出的执行,遇到next就去执行下一个中间件里的next前面方法。
// 执行函数
c.Next()
// 中间件执行完后续的一些事情
局部中间件
局部中间件意味着部分接口才会生效,只在局部使用,这时候访问http:127.0.0.1:8000/ 才会看到中间件的日志打印,其他API接口则不会出现。
//局部中间件使用
r.GET("/", MiddleWare(), func(c *gin.Context) {
// 取值
req, _ := c.Get("request")
fmt.Println("request:", req)
// 页面接收
c.JSON(200, gin.H{"request": req})
})
gin内置中间件
func BasicAuth(accounts Accounts) HandlerFunc
func BasicAuthForRealm(accounts Accounts, realm string) HandlerFunc
func Bind(val interface{}) HandlerFunc
func ErrorLogger() HandlerFunc
func ErrorLoggerT(typ ErrorType) HandlerFunc
func Logger() HandlerFunc
func LoggerWithConfig(conf LoggerConfig) HandlerFunc
func LoggerWithFormatter(f LogFormatter) HandlerFunc
func LoggerWithWriter(out io.Writer, notlogged ...string) HandlerFunc
func Recovery() HandlerFunc
func RecoveryWithWriter(out io.Writer) HandlerFunc
func WrapF(f http.HandlerFunc) HandlerFunc
func WrapH(h http.Handler) HandlerFunc
总结
通过自定义中间件,我们可以很方便的拦截请求,来做一些我们需要做的事情,比如日志记录、授权校验、各种过滤等等。