中间件注册必须用app.Use(),不可用app.UseRouter()(Iris无此函数);全局中间件通过app.Use()注入,路由级中间件需作为参数传入如app.Get("/path", middleware, handler),路径参数必须用ctx.Params().Get()获取,而非ctx.URLParam()。

中间件注册必须用 app.Use(),不是 app.UseRouter() 或其他变体
常见错误是把中间件当成路由处理器传给 app.Get() 或误写成 app.UseRouter() —— Iris 没有这个函数。中间件只能通过 app.Use()(全局)或路由级参数(如 app.Get("/path", middleware, handler))注入。
-
app.Use()注册的中间件对所有匹配路由生效,包括子路由组 - 若只对某组路由生效,应配合
app.Party()使用:admin := app.Party("/admin"); admin.Use(authMiddleware) - 中间件函数签名必须是
func(iris.Context),不能少参数或多参数 - 忘记调用
ctx.Next()会导致后续中间件和 handler 不执行;但写完响应后(如ctx.StatusCode(401))必须调用ctx.StopExecution(),否则仍会继续往下走
ctx.Params().Get() 是取路径参数的唯一正确方式
很多人在中间件里用 ctx.URLParam("name") 尝试读取 /user/{id} 中的 id,结果返回空。这是因为 ctx.URLParam() 只读查询参数(?id=123),而路径参数必须用 ctx.Params().Get("id")。
- 路径参数名来自路由定义,比如
app.Get("/user/{uid:int64}", handler)→ 用ctx.Params().Get("uid") - 类型约束(如
:int64)只做路由匹配校验,不自动转换类型;你仍需手动strconv.ParseInt() - 若参数名拼错或路由未命中,
ctx.Params().Get()返回空字符串,不会 panic
全局中间件和路由级中间件的执行顺序容易混淆
执行顺序是「全局前置 → 路由级前置 → handler → 路由级后置(app.Done())→ 全局后置(app.Done())」,但很多人以为 app.Done() 是“最后统一执行”,其实它只是注册后置钩子,且只对当前 app 实例有效。
-
app.Use(m1); app.Done(m2); app.Get("/x", h)→ 执行顺序:m1 → h → m2 -
admin := app.Party("/admin"); admin.Use(m3); admin.Done(m4)→ /admin 下的请求:m1 → m3 → h → m4 → m2 -
app.Done()不会覆盖已注册的全局后置,而是追加;多次调用会按注册顺序依次执行 - 若中间件中写了响应但没调用
ctx.StopExecution(),后续中间件仍会执行,可能重复写响应导致http: multiple response.WriteHeader calls错误
中间件里别直接 panic,要用 recover.New() 或自己捕获
Iris 默认不 recover panic,一旦中间件或 handler panic,整个 HTTP 连接会断开,日志里只显示 goroutine crash,没有堆栈上下文。线上服务基本不可接受。
- 最简方案:在
app.Use()中注册recover.New(),它会自动捕获 panic 并返回 500 - 自定义 recover 中间件时,必须用
defer+recover(),且在ctx.StatusCode(500)后立即ctx.StopExecution() - 不要在中间件里用
log.Fatal或os.Exit,这会杀死整个进程,不是单个请求 - 日志记录建议用
app.Logger().Errorf(),而不是fmt.Println(),否则无法集中收集
ctx.Params().Get() 和 ctx.URLParam() 的混用,以及漏掉 StopExecution(),是线上最常见的两类故障源。


















