中间件
什么是中间件?
在 Go 语言中,中间件是一种用于处理请求和响应的函数或方法。它们可以被插入到请求处理流程中,在请求到达最终处理程序之前或之后执行一些额外的操作。
中间件有什么用?
中间件的主要作用是在请求和响应之间添加一层逻辑,用于处理常见的功能和任务,例如:
- 路由和权限控制:中间件可以用于验证请求的路由和权限,确保只有经过认证和授权的用户可以访问特定的路由。
- 身份验证和授权:中间件可以用于验证用户身份,并检查用户是否具有执行某个操作的权限。
- 请求记录和日志:中间件可以记录请求的详细信息,如请求方法、路径、参数等,以及响应的状态码、响应时间等,方便调试和监控应用程序。
- 错误处理和恢复:中间件可以捕获处理程序中的错误,并返回适当的错误响应。它们还可以在发生错误时进行恢复,避免应用程序崩溃并提供友好的错误提示。
- 缓存和性能优化:中间件可以实现请求结果的缓存,以提高应用程序的性能,当相同的请求再次到达时,可以直接返回缓存的响应,而无需执行后续的处理程序。
- 请求转发和反向代理:中间件可以实现请求的转发、反向代理或负载均衡,通过将请求发送给其他服务或处理程序进行处理。
在 Go 中,中间件通常是一个接收 http.Handler 或 http.HandlerFunc 参数的函数,并返回一个经过处理的新的 http.Handler 或 http.HandlerFunc。这样可以构建出一个处理请求的链,每个中间件都可以在请求到达最终处理程序之前/之后执行一些操作,对请求进行处理或修改。
使用中间件可以提高代码的可重用性、模块化和可读性。它们使得处理请求的逻辑更加清晰,并允许开发人员在不修改核心业务逻辑的情况下添加各种功能和扩展。
全局中间件
全局中间件是指应用于整个应用程序的中间件,它们会对所有请求生效。
package main
import (
"fmt"
"time"
"github.com/gin-gonic/gin"
)
// 定义中间件
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)
}
}
func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
// 注册中间件
r.Use(MiddleWare())
// {}为了代码规范
{
r.GET("/ce", func(c *gin.Context) {
// 取值
req, _ := c.Get("request")
fmt.Println("request:", req)
// 页面接收
c.JSON(200, gin.H{"request": req})
})
}
r.Run()
}
Next()方法
在 Gin 框架中,c.Next() 方法是用于在中间件函数中手动将控制权传递给下一个处理函数的方法。
当中间件函数执行到 c.Next() 时,它会停止当前中间件的执行并将控制权交给下一个处理函数。这通常用于在中间件中执行一些预处理操作,然后将请求继续传递给下一个中间件或路由处理函数。
package main
import (
"fmt"
"time"
"github.com/gin-gonic/gin"
)
// 定义中间
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
fmt.Println("中间件开始执行了")
// 设置变量到Context的key中,可以通过Get()取
c.Set("request", "中间件")
// 执行函数
c.Next()
// 中间件执行完后续的一些事情
status := c.Writer.Status()
fmt.Println("中间件执行完毕", status)
t2 := time.Since(t)
fmt.Println("time:", t2)
}
}
func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
// 注册中间件
r.Use(MiddleWare())
// {}为了代码规范
{
r.GET("/ce", func(c *gin.Context) {
// 取值
req, _ := c.Get("request")
fmt.Println("request:", req)
// 页面接收
c.JSON(200, gin.H{"request": req})
})
}
r.Run()
}
局部中间件
局部中间件是指仅应用于特定路由或路由组的中间件。这些中间件只对指定的路由或路由组生效,而不会影响其他路由。
package main
import (
"fmt"
"time"
"github.com/gin-gonic/gin"
)
// 定义中间
func MiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
t := time.Now()
fmt.Println("中间件开始执行了")
// 设置变量到Context的key中,可以通过Get()取
c.Set("request", "中间件")
// 执行函数
c.Next()
// 中间件执行完后续的一些事情
status := c.Writer.Status()
fmt.Println("中间件执行完毕", status)
t2 := time.Since(t)
fmt.Println("time:", t2)
}
}
func main() {
// 1.创建路由
// 默认使用了2个中间件Logger(), Recovery()
r := gin.Default()
//局部中间键使用
r.GET("/ce", MiddleWare(), func(c *gin.Context) {
// 取值
req, _ := c.Get("request")
fmt.Println("request:", req)
// 页面接收
c.JSON(200, gin.H{"request": req})
})
r.Run()
}