路由级中间件 #
一、路由级中间件概述 #
1.1 什么是路由级中间件 #
路由级中间件是应用于特定路由或路由分组的中间件,只对该路由或分组内的请求生效:
go
func main() {
r := gin.New()
// 全局中间件
r.Use(gin.Logger())
// 分组中间件
api := r.Group("/api")
api.Use(AuthMiddleware())
{
// 路由中间件
api.GET("/admin", AdminMiddleware(), adminHandler)
}
r.Run()
}
1.2 中间件层级 #
text
请求
↓
全局中间件
↓
分组中间件
↓
路由中间件
↓
处理函数
二、分组中间件 #
2.1 基本用法 #
go
func main() {
r := gin.New()
// 需要认证的API分组
api := r.Group("/api")
api.Use(AuthMiddleware())
{
api.GET("/profile", getProfile)
api.GET("/settings", getSettings)
}
// 公开API分组
public := r.Group("/public")
{
public.GET("/info", getPublicInfo)
}
r.Run()
}
2.2 多级分组 #
go
func main() {
r := gin.New()
// API分组
api := r.Group("/api")
api.Use(LoggerMiddleware())
{
// v1版本
v1 := api.Group("/v1")
v1.Use(VersionMiddleware("v1"))
{
// 用户资源
users := v1.Group("/users")
users.Use(AuthMiddleware())
{
users.GET("", listUsers)
users.GET("/:id", getUser)
}
// 公开资源
public := v1.Group("/public")
{
public.GET("/info", getInfo)
}
}
// v2版本
v2 := api.Group("/v2")
v2.Use(VersionMiddleware("v2"))
{
users := v2.Group("/users")
users.Use(AuthMiddleware())
users.Use(RateLimitMiddleware(100))
{
users.GET("", listUsersV2)
}
}
}
r.Run()
}
2.3 中间件继承 #
go
func main() {
r := gin.New()
// 父分组中间件会被子分组继承
api := r.Group("/api")
api.Use(Middleware1()) // 子分组会继承
{
// 继承Middleware1,并添加Middleware2
users := api.Group("/users")
users.Use(Middleware2())
{
// 继承Middleware1和Middleware2,并添加Middleware3
admin := users.Group("/admin")
admin.Use(Middleware3())
{
admin.GET("", adminHandler)
// 执行顺序: Middleware1 → Middleware2 → Middleware3 → handler
}
}
}
r.Run()
}
三、单路由中间件 #
3.1 基本用法 #
go
func main() {
r := gin.New()
// 单个路由添加中间件
r.GET("/profile", AuthMiddleware(), getProfile)
// 多个中间件
r.GET("/admin",
AuthMiddleware(),
AdminMiddleware(),
adminHandler,
)
r.Run()
}
3.2 中间件链 #
go
func main() {
r := gin.New()
r.GET("/protected",
func(c *gin.Context) {
fmt.Println("中间件1")
c.Next()
},
func(c *gin.Context) {
fmt.Println("中间件2")
c.Next()
},
func(c *gin.Context) {
fmt.Println("处理函数")
c.String(200, "ok")
},
)
r.Run()
}
四、条件中间件 #
4.1 基于路径条件 #
go
func ConditionalMiddleware(pattern string, middleware gin.HandlerFunc) gin.HandlerFunc {
return func(c *gin.Context) {
if matched, _ := path.Match(pattern, c.Request.URL.Path); matched {
middleware(c)
return
}
c.Next()
}
}
func main() {
r := gin.New()
// 只对/admin/*路径应用认证
r.Use(ConditionalMiddleware("/admin/*", AuthMiddleware()))
r.GET("/public", publicHandler) // 不需要认证
r.GET("/admin/users", adminHandler) // 需要认证
r.Run()
}
4.2 基于方法条件 #
go
func MethodMiddleware(method string, middleware gin.HandlerFunc) gin.HandlerFunc {
return func(c *gin.Context) {
if c.Request.Method == method {
middleware(c)
return
}
c.Next()
}
}
func main() {
r := gin.New()
// 只对POST请求应用验证
r.Use(MethodMiddleware("POST", ValidationMiddleware()))
r.GET("/users", listUsers) // 不需要验证
r.POST("/users", createUser) // 需要验证
r.Run()
}
4.3 基于请求头条件 #
go
func HeaderMiddleware(header, value string, middleware gin.HandlerFunc) gin.HandlerFunc {
return func(c *gin.Context) {
if c.GetHeader(header) == value {
middleware(c)
return
}
c.Next()
}
}
func main() {
r := gin.New()
// 只对特定版本的API应用中间件
r.Use(HeaderMiddleware("API-Version", "v2", V2Middleware()))
r.Run()
}
4.4 自定义条件 #
go
func When(condition func(*gin.Context) bool, middleware gin.HandlerFunc) gin.HandlerFunc {
return func(c *gin.Context) {
if condition(c) {
middleware(c)
return
}
c.Next()
}
}
func main() {
r := gin.New()
// 自定义条件:只对特定用户应用中间件
r.Use(When(func(c *gin.Context) bool {
return c.GetHeader("X-User-Type") == "premium"
}, PremiumMiddleware()))
r.Run()
}
五、中间件组合 #
5.1 组合多个中间件 #
go
func Chain(middlewares ...gin.HandlerFunc) gin.HandlerFunc {
return func(c *gin.Context) {
for _, m := range middlewares {
m(c)
if c.IsAborted() {
return
}
}
}
}
func main() {
r := gin.New()
// 组合多个中间件
r.GET("/protected",
Chain(
AuthMiddleware(),
RateLimitMiddleware(100),
PermissionMiddleware("read"),
),
handler,
)
r.Run()
}
5.2 中间件工厂 #
go
type MiddlewareBuilder struct {
middlewares []gin.HandlerFunc
}
func NewMiddlewareBuilder() *MiddlewareBuilder {
return &MiddlewareBuilder{}
}
func (b *MiddlewareBuilder) Auth() *MiddlewareBuilder {
b.middlewares = append(b.middlewares, AuthMiddleware())
return b
}
func (b *MiddlewareBuilder) RateLimit(rps int) *MiddlewareBuilder {
b.middlewares = append(b.middlewares, RateLimitMiddleware(rps))
return b
}
func (b *MiddlewareBuilder) Permission(perm string) *MiddlewareBuilder {
b.middlewares = append(b.middlewares, PermissionMiddleware(perm))
return b
}
func (b *MiddlewareBuilder) Build() gin.HandlerFunc {
return Chain(b.middlewares...)
}
func main() {
r := gin.New()
// 使用构建器创建中间件链
middleware := NewMiddlewareBuilder().
Auth().
RateLimit(100).
Permission("admin").
Build()
r.GET("/admin", middleware, adminHandler)
r.Run()
}
六、实际应用场景 #
6.1 API版本控制 #
go
func main() {
r := gin.New()
v1 := r.Group("/api/v1")
v1.Use(V1Middleware())
{
v1.GET("/users", listUsersV1)
}
v2 := r.Group("/api/v2")
v2.Use(V2Middleware())
v2.Use(DeprecationWarning())
{
v2.GET("/users", listUsersV2)
}
r.Run()
}
func DeprecationWarning() gin.HandlerFunc {
return func(c *gin.Context) {
c.Header("X-API-Deprecated", "true")
c.Header("X-API-Sunset", "2024-12-31")
c.Next()
}
}
6.2 权限控制 #
go
func RequirePermission(permission string) gin.HandlerFunc {
return func(c *gin.Context) {
userRole, _ := c.Get("role")
if !hasPermission(userRole.(string), permission) {
c.AbortWithStatusJSON(403, gin.H{
"code": 403,
"message": "权限不足",
})
return
}
c.Next()
}
}
func main() {
r := gin.New()
r.Use(AuthMiddleware())
users := r.Group("/users")
{
users.GET("", RequirePermission("user:read"), listUsers)
users.POST("", RequirePermission("user:create"), createUser)
users.PUT("/:id", RequirePermission("user:update"), updateUser)
users.DELETE("/:id", RequirePermission("user:delete"), deleteUser)
}
r.Run()
}
6.3 资源所有权验证 #
go
func ResourceOwner(resourceType string) gin.HandlerFunc {
return func(c *gin.Context) {
userId := c.GetString("userId")
resourceId := c.Param("id")
if !isOwner(userId, resourceType, resourceId) {
c.AbortWithStatusJSON(403, gin.H{
"code": 403,
"message": "无权访问此资源",
})
return
}
c.Next()
}
}
func main() {
r := gin.New()
r.Use(AuthMiddleware())
r.GET("/posts/:id", ResourceOwner("post"), getPost)
r.PUT("/posts/:id", ResourceOwner("post"), updatePost)
r.DELETE("/posts/:id", ResourceOwner("post"), deletePost)
r.Run()
}
6.4 功能开关 #
go
func FeatureFlag(feature string) gin.HandlerFunc {
return func(c *gin.Context) {
if !isFeatureEnabled(feature) {
c.AbortWithStatusJSON(404, gin.H{
"code": 404,
"message": "功能未开放",
})
return
}
c.Next()
}
}
func main() {
r := gin.New()
r.GET("/beta", FeatureFlag("beta_feature"), betaHandler)
r.Run()
}
七、中间件调试 #
7.1 打印中间件链 #
go
func main() {
r := gin.New()
r.Use(func(c *gin.Context) {
fmt.Println("全局中间件")
c.Next()
})
api := r.Group("/api")
api.Use(func(c *gin.Context) {
fmt.Println("分组中间件")
c.Next()
})
{
api.GET("/test",
func(c *gin.Context) {
fmt.Println("路由中间件")
c.Next()
},
func(c *gin.Context) {
fmt.Println("处理函数")
c.String(200, "ok")
},
)
}
// 打印路由信息
routes := r.Routes()
for _, route := range routes {
fmt.Printf("%s %s\n", route.Method, route.Path)
}
r.Run()
}
7.2 中间件性能分析 #
go
func TimingMiddleware(name string) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
c.Next()
duration := time.Since(start)
log.Printf("[%s] took %v", name, duration)
}
}
func main() {
r := gin.New()
r.Use(TimingMiddleware("global"))
api := r.Group("/api")
api.Use(TimingMiddleware("group"))
{
api.GET("/test", TimingMiddleware("route"), func(c *gin.Context) {
c.String(200, "ok")
})
}
r.Run()
}
八、总结 #
8.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 分组中间件 | Group().Use(middleware) |
| 路由中间件 | GET(path, middleware, handler) |
| 中间件继承 | 子分组继承父分组中间件 |
| 条件中间件 | 根据条件决定是否执行 |
8.2 最佳实践 #
| 实践 | 说明 |
|---|---|
| 合理分层 | 全局、分组、路由级别 |
| 单一职责 | 每个中间件只做一件事 |
| 条件判断 | 使用条件中间件减少重复 |
| 权限控制 | 路由级权限验证 |
8.3 下一步 #
现在你已经掌握了路由级中间件,接下来让我们学习 自定义中间件,编写自己的中间件!
最后更新:2026-03-28