e.use() 是挂载全局中间件的唯一正确入口,必须在注册任何路由前调用,否则中间件不生效;其执行遵循洋葱模型,请求时顺序进入、响应时逆序返回,且 e.use() 优先于 group.use(),共同构成嵌套执行链。

e.Use() 是挂载全局中间件的唯一正确入口,不是 e.GET() 或 e.Group().Use()。
必须在注册任何路由前调用 e.Use(),否则中间件不会被触发——这是洋葱模型的硬性约束,不是可选建议。
e.Use() 必须在 e.GET() 之前调用
Echo 的请求处理是严格洋葱式:请求进来时按 e.Use() 注册顺序执行,响应返回时逆序执行。
一旦路由已注册,后续 e.Use() 调用对已有路由完全无效。
-
常见错误写法(中间件不生效):
e.GET("/api/data", handler) e.Use(middleware.Logger()) // ❌ 晚了,/api/data 已绑定,这个 Logger 根本不会进它的请求流 -
正确顺序:
e.Use(middleware.Logger()) e.Use(middleware.Recover()) e.Use(cacheMiddleware) // 所有中间件都得在这一步到位 e.GET("/api/data", handler) // ✅ 此时 handler 被包裹在完整中间件链里 如果你用
e.Group()定义了/v1,它也受e.Use()全局链影响;不需要、也不应该在 group 内重复Use()来“补”全局逻辑。
全局中间件和路由组中间件的执行关系
e.Use() 注册的是最外层洋葱皮,所有请求必经;而 group.Use() 是嵌套在其中的更内层。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
- 执行顺序示例(假设注册顺序如下):
e.Use(A) // 第一层(最外) e.Use(B) // 第二层 api := e.Group("/api") api.Use(C) // 第三层(仅 /api 及其子路由进入) api.GET("/users", handler)
请求 /api/users 的执行流是:A → B → C → handler → C ← B ← A
非 /api 下的路径(如 /health)只走 A → B → handler → B ← A
- 注意:
group.Use()不会覆盖或跳过e.Use(),只是追加;但反过来,e.Use()无法感知 group 内部是否用了某个中间件。
中间件函数签名与返回值陷阱
全局中间件函数必须符合 echo.MiddlewareFunc 类型:func(next echo.HandlerFunc) echo.HandlerFunc
-
错误示范(直接 return error):
func brokenMiddleware(next echo.HandlerFunc) error { return next(c) // ❌ 编译失败:类型不匹配 } -
正确写法(必须返回 handler):
func authMiddleware(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { if !isValidToken(c.Request().Header.Get("Authorization")) { return c.NoContent(http.StatusUnauthorized) } return next(c) // ✅ 必须显式调用 next(c),否则链断开 } } 漏掉
return next(c)是静默故障:请求卡住、超时、无响应——日志里也不会报错。
缓存中间件这类依赖请求/响应生命周期的逻辑,特别容易因挂载时机或链断裂而失效;真正难的不是写中间件,而是确保它稳稳落在洋葱最外层且全程参与。










