暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Golang Web开发之Gin Middleware

一起Go技术 2021-10-30
1527

声明:这是一个系列,系列中,我将为您介绍Gin框架



在本文中,我将为您介绍,Gin框架的Middleware中间件(下文统称Middleware)是什么,并介绍一些场景和案例。


Gin Middleware


Gin中提供了 Middleware 的功能,您可以使用该功能做一些事情。下面为您阐述它。


1. 什么是Middleware

在Gin中,Middleware 是可以拦截http请求-响应生命周期的特殊函数。若您想拦截所有请求做一些事情,那么可以利用一个 Middleware 函数实现您想做的事情。在HTTP请求-响应的生命周期中,您可以注册多个 Middleware,每个 Middleware 执行不同的功能,一个 Middleware 执行完再轮到下一个 Middleware 执行。

2. 常见使用场景

Middleware 的使用场景比较多。这里为您列出一些它的使用场景,供参考:

1、日志审计

2、权限校验

3、请求限速

4、统一错误处理

■ ■■■

3. Middleware作用范围

在Gin中,根据作用范围可大体分全局和局部的 Middleware。设置全局Middleware会拦截所有请求(即所有的请求都会经过该类型的 Middleware );针对分组路由设置 Middleware 或针对某些个路由设置,则仅对这个分组下的路由或某些个路由起作用。

如果您使用gin.Default()创建了一个引擎,则使用了Recovery和Logger两个Middleware 。Recovery用于拦截panic错误,不至于导致进程崩掉;Logger主要用于打印请求日志。如下:

func main() {
// 创建一个r,这一行相当于下面几行
// 默认使用了Logger(), Recovery()
r := gin.Default()


// 相当于上面的作用
r := gin.New()
r.Use(gin.Logger())
r.Use(gin.Recovery())
}

■ ■■■


4. 全局Middleware

如果您想要设置一个自己的全局 Middleware,那么您可以参考如下示例:
package main
import (
"fmt"
"time"

"github.com/gin-gonic/gin"
)


// 定义中间件
func SelfDefinedMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t1 := time.Now()
fmt.Println("开始执行中间件")
// 设置您的变量到Context的key中,后续可在控制器逻辑中通过Get()拿到
c.Set("key1", "value1")
status := c.Writer.Status()
fmt.Println("结束执行中间件", status)
t2 := time.Since(t1)
fmt.Println("time:", t2)
}
}


func main() {
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
// 注册中间件
r.Use(SelfDefinedMiddleWare())
{
r.GET("/test_global_middleWare", func(c *gin.Context) {
value1, _ := c.Get("key1")
fmt.Println("value1:", value1)
c.JSON(200, gin.H{"value1": value1})
})
}
r.Run()
}

您现在将以上代码运行起来后,用postman测试一把:


很显然,一个自定义的全局 Middleware 就已经起作用了:

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.


[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)


[GIN-debug] GET /test_global_middleWare --> main.main.func1 (4 handlers)
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
开始执行中间件
结束执行中间件 200
time: 295µs
value1: value1
[GIN] 2021/10/14 - 10:28:50 | 200 |      1.3293ms |       127.0.0.1 | GET      "/test_global_middleWare"

■ ■■■


5. 局部Middleware

如果您想要设置一个自己的局部 Middleware ,那么您可以参考如下示例:
package main
import (
    "fmt"
    "time"
   
"github.com/gin-gonic/gin"
)


// 定义中间件
func SelfDefinedMiddleWare() gin.HandlerFunc {
    return func(c *gin.Context) {
        t1 := time.Now()
        fmt.Println("开始执行中间件")


        // 设置您的变量到Context的key中,后续可在控制器逻辑中通过Get()拿到
        c.Set("key1", "value1")
        status := c.Writer.Status()


        fmt.Println("结束执行中间件", status)
        t2 := time.Since(t1)
        fmt.Println("time:", t2)
    }
}


func main() {
    // 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()


    {
        // 设置中间件
        r.GET("/test_local_middleware", SelfDefinedMiddleWare(), func(c *gin.Context) {
            value1, _ := c.Get("key1")
            fmt.Println("value1:", value1)
            c.JSON(200, gin.H{"value1": value1})
        })


        r.GET("/hi", func(c *gin.Context) {
            c.String(200, "hello")
        })
    }
    r.Run()
}


现在,将代码运行起来,可以分别测试这两个API了观察现象了:






很显然,/hi这个api是不会被我们刚才自定义的 Middleware 拦截的。

■ ■■■



总结


本文主要介绍了在Gin中 Middleware 的概念和它的一些使用场景,另外,文中也介绍了 Middleware 是由作用范围的,您可以根据使用需要自行选择。


后续,我将继续为您介绍Gin的一些其他教程,敬请期待~~。




  end 
👇👇👇👇👇👇

长按二维码关注我们吧


不要错过



因为你的分享、点赞、在看
我足足的精气神儿!



文章转载自一起Go技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论