理解后端开发中的中间件(以gin框架为例)

中间件(Middleware)是后端开发中的一个核心概念,它在请求(Request)和响应(Response)之间扮演着桥梁角色。以下是关于中间件的详细解释:

基本概念

中间件是在请求到达最终处理程序之前或响应返回客户端之前执行的一系列函数或组件。它可以:

  • 访问请求对象(req)、响应对象(res)

  • 执行任意代码

  • 修改请求和响应对象

  • 结束请求-响应周期

  • 调用堆栈中的下一个中间件

中间件的工作原理

典型的中间件工作流程:

复制代码
客户端请求 → 中间件1 → 中间件2 → ... → 路由处理 → 中间件N → ... → 中间件2 → 中间件1 → 客户端响应

以下用一个例子来说明

go 复制代码
package main

import (
	"github.com/gin-gonic/gin"
	"log"
	"time"
)

func main() {
	r := gin.New()
	
	// 中间件1:记录请求开始时间
	r.Use(func(c *gin.Context) {
		log.Println("中间件1 - 开始")
		start := time.Now()
		c.Set("startTime", start) // 在上下文中存储数据
		
		// 模拟从Header获取用户信息
		user := c.GetHeader("X-User")
		if user != "" {
			c.Set("user", user)
		}
		
		c.Next() // 移交控制权给下一个中间件/处理程序
		
		latency := time.Since(start)
		log.Printf("中间件1 - 结束, 耗时: %v", latency)
	})
	
	// 中间件2:认证检查
	r.Use(func(c *gin.Context) {
		log.Println("中间件2 - 认证检查")
		if c.GetHeader("X-Token") != "my-secret-token" {
			c.AbortWithStatusJSON(401, gin.H{"error": "认证失败"})
			// 注意:这里没有调用c.Next(),请求处理被中断
			return
		}
		c.Next()
	})
	
	// 路由处理
	r.GET("/hello", func(c *gin.Context) {
		log.Println("主处理函数 - 开始处理")
		
		// 从上下文中获取中间件设置的数据
		user, exists := c.Get("user")
		if exists {
			log.Printf("当前用户: %v", user)
		}
		
		time.Sleep(100 * time.Millisecond) // 模拟业务处理耗时
		c.JSON(200, gin.H{"message": "Hello World"})
		
		log.Println("主处理函数 - 处理完成")
	})
	
	r.Run(":8080")
}

处理流程如下:

1. 请求进入
  • 中间件1开始执行,记录开始时间,设置user信息
  • 调用 c.Next() 进入下一个中间件
2. 认证检查
  • 中间件2检查token,验证通过
  • 调用 c.Next() 进入路由处理函数
3. 主处理
  • 路由函数执行业务逻辑
  • 返回JSON响应
4. 反向回溯
  • 返回到中间件2(但它没有 c.Next() 后的代码)
  • 返回到中间件1,计算并记录耗时

请求进入 中间件1前 中间件2前 ... 路由处理 ... 中间件2后 中间件1后 响应返回

相关推荐
不会写DN8 小时前
通过eino-ext如何正常indexer RAG?
网络·面试·go
donecoding8 小时前
遗嘱、水管与抢救室:TS 切入 Go 的流程控制、接口与并发
javascript·typescript·go
扉页的墨9 小时前
Go 协程泄漏排查实战:我是如何把线上内存从 500MB 压到 20MB 的
go
donecoding9 小时前
对象模型与内存的“钥匙理论”:TS 切入的 Go 的结构体与指针
javascript·typescript·go
我叫黑大帅19 小时前
通过eino-ext如何正常indexer RAG?
后端·面试·go
审判长烧鸡1 天前
GO闭包【4】“普通闭包”与“循环闭包”之间捕获的核心区别
go·捕获·闭包
fuquxiaoguang1 天前
住房公积金数字化建设中的四层思考:以江苏实践为例
中间件·自主可控·公积金平台·协通伟业
审判长烧鸡1 天前
Go 闭包【1】基础
go·闭包
是小蟹呀^1 天前
【总结】LangChain中的中间件Middleware
python·中间件·langchain·agent
fuquxiaoguang1 天前
从47个接口到全栈适配:医疗信创的“重建”之路
中间件·医疗·金蝶天燕