From fce12ee7e7418ec0d6e56d4bf7e714acf50822f5 Mon Sep 17 00:00:00 2001 From: wjqserver <114663932+WJQSERVER@users.noreply.github.com> Date: Tue, 21 Apr 2026 18:19:44 +0800 Subject: [PATCH 1/2] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E4=BB=B6=E6=96=87=E6=A1=A3=EF=BC=8C=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=B7=AF=E7=94=B1=E7=BA=A7=E4=B8=AD=E9=97=B4=E4=BB=B6=E5=92=8C?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E9=A1=BA=E5=BA=8F=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加路由级中间件使用示例 - 说明在创建组时直接传入中间件的方法 - 添加中间件执行顺序章节,清晰展示全局/组/路由中间件的执行流程 --- docs/middleware.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/docs/middleware.md b/docs/middleware.md index a222437..14c75d6 100644 --- a/docs/middleware.md +++ b/docs/middleware.md @@ -26,6 +26,41 @@ api.Use(AuthMiddleware()) } ``` +也可以在创建组时直接传入中间件: + +```go +api := r.Group("/api", AuthMiddleware(), RateLimitMiddleware()) +{ + api.GET("/user", handleUser) + api.POST("/data", handleData) +} +``` + +### 路由级中间件 + +为单个路由注册中间件,仅对该路由生效。 + +```go +// 单个路由中间件 +r.GET("/protected", AuthMiddleware(), func(c *touka.Context) { + c.String(http.StatusOK, "Protected content") +}) + +// 多个路由中间件(按顺序执行) +r.POST("/upload", + RateLimitMiddleware(), + AuthMiddleware(), + PermissionCheckMiddleware(), + func(c *touka.Context) { + // 处理上传 + }, +) + +// 路由组中的单个路由也可以使用路由级中间件 +api := r.Group("/api") +api.GET("/admin", AdminAuthMiddleware(), adminHandler) +``` + ## 编写自定义中间件 中间件的函数签名是 `touka.HandlerFunc`。 @@ -67,6 +102,36 @@ func APIKeyAuth() touka.HandlerFunc { } ``` +## 中间件执行顺序 + +理解中间件的执行顺序对于构建正确的处理流程至关重要。中间件按照以下顺序执行: + +```go +// 全局中间件 +r.Use(GlobalMiddleware1()) +r.Use(GlobalMiddleware2()) + +// 组中间件 +api := r.Group("/api", GroupMiddleware1()) +api.Use(GroupMiddleware2()) + +// 路由级中间件 +api.GET("/users", RouteMiddleware1(), RouteMiddleware2(), userHandler) +``` + +对于 `/api/users` 请求,执行顺序为: +1. `GlobalMiddleware1()` - 全局中间件 +2. `GlobalMiddleware2()` - 全局中间件 +3. `GroupMiddleware1()` - 组中间件 +4. `GroupMiddleware2()` - 组中间件 +5. `RouteMiddleware1()` - 路由级中间件 +6. `RouteMiddleware2()` - 路由级中间件 +7. `userHandler` - 最终处理函数 + +``` +请求进入 → 全局中间件 → 组中间件 → 路由中间件 → 处理函数 → 路由中间件后置逻辑 → 组中间件后置逻辑 → 全局中间件后置逻辑 → 响应 +``` + ## 内置中间件 - **Recovery**: 捕获任何发生的 panic,恢复运行并返回 500 错误。它还负责调用全局错误处理器。 From 58fd877ae269cb7ca3799fc8f5b2c3fa4f5aaec5 Mon Sep 17 00:00:00 2001 From: wjqserver <114663932+WJQSERVER@users.noreply.github.com> Date: Tue, 21 Apr 2026 18:32:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=E4=BF=AE=E5=A4=8D=E5=AE=A1?= =?UTF-8?q?=E6=9F=A5=E6=84=8F=E8=A7=81=EF=BC=8C=E7=BB=9F=E4=B8=80=E6=9C=AF?= =?UTF-8?q?=E8=AF=AD=E5=B9=B6=E8=A1=A5=E5=85=85=E6=B3=A8=E5=86=8C=E9=A1=BA?= =?UTF-8?q?=E5=BA=8F=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 补充中间件注册顺序说明(必须在路由定义之前) - 统一术语:'组中间件' → '路由组中间件' - 统一流程图术语 --- docs/middleware.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/middleware.md b/docs/middleware.md index 14c75d6..b688fb5 100644 --- a/docs/middleware.md +++ b/docs/middleware.md @@ -104,7 +104,7 @@ func APIKeyAuth() touka.HandlerFunc { ## 中间件执行顺序 -理解中间件的执行顺序对于构建正确的处理流程至关重要。中间件按照以下顺序执行: +理解中间件的执行顺序对于构建正确的处理流程至关重要。**注意:注册顺序决定了执行逻辑**,中间件必须在注册路由之前调用(全局中间件应在创建组或定义路由前注册)。中间件按照以下顺序执行: ```go // 全局中间件 @@ -122,14 +122,14 @@ api.GET("/users", RouteMiddleware1(), RouteMiddleware2(), userHandler) 对于 `/api/users` 请求,执行顺序为: 1. `GlobalMiddleware1()` - 全局中间件 2. `GlobalMiddleware2()` - 全局中间件 -3. `GroupMiddleware1()` - 组中间件 -4. `GroupMiddleware2()` - 组中间件 +3. `GroupMiddleware1()` - 路由组中间件 +4. `GroupMiddleware2()` - 路由组中间件 5. `RouteMiddleware1()` - 路由级中间件 6. `RouteMiddleware2()` - 路由级中间件 7. `userHandler` - 最终处理函数 ``` -请求进入 → 全局中间件 → 组中间件 → 路由中间件 → 处理函数 → 路由中间件后置逻辑 → 组中间件后置逻辑 → 全局中间件后置逻辑 → 响应 +请求进入 → 全局中间件 → 路由组中间件 → 路由级中间件 → 最终处理函数 → 路由级中间件后置逻辑 → 路由组中间件后置逻辑 → 全局中间件后置逻辑 → 响应 ``` ## 内置中间件