自定义 context 必须内嵌 iris.context,通过 app.wraprouter 注入;首字段为未导出的 iris.context 以保证方法继承;需手动清理 values/params 防复用污染;新增方法不得覆盖原生签名。

自定义 Context 类型必须嵌入原生 iris.Context
Iris 不允许你完全替换 Context 接口,因为框架内部强依赖其方法签名(如 ResponseWriter()、Request()、Next() 等)。你只能通过「组合」方式扩展:定义一个新结构体,内嵌 iris.Context,再添加自己的字段或方法。
常见错误是试图实现完整接口或重写 Context 类型——这会导致路由无法调用中间件、ctx.Next() 失效、甚至 panic。
- 正确做法:结构体首字段必须是
iris.Context(保证内存布局兼容) - 不要导出该字段(即写成
ctx iris.Context而非Ctx iris.Context),否则会破坏iris.Context的方法集继承 - 所有新增方法都应接收指针 receiver,避免值拷贝丢失上下文状态
app.WrapRouter 是注入自定义上下文的唯一入口
Iris 在每次请求到来时从 sync.Pool 分配 Context 实例,你无法在 handler 中“中途替换”它。真正可控的时机只有路由器分发前——也就是 app.WrapRouter 回调里。
这个函数接收原始 iris.Context,返回你包装后的上下文实例。框架后续所有操作(包括中间件链、路由匹配、handler 执行)都基于你返回的对象。
- 必须返回实现了
iris.Context接口的类型(靠内嵌自动满足) - 不能返回
nil,否则请求直接 500 - 若需传递额外数据(如用户 ID、trace ID),应在 WrapRouter 中完成初始化,而非依赖 handler 里的临时赋值
示例:
type MyContext struct {
iris.Context
userID int64
traceID string
}
app.WrapRouter(func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) {
ctx := app.NewContext(w, r)
myCtx := &MyContext{
Context: ctx,
userID: extractUserID(r),
traceID: getTraceID(r),
}
router(w, r, func() {
// 此处执行路由逻辑,ctx 已被替换为 myCtx
myCtx.Do() // 可安全调用自定义方法
})
})
自定义方法要避免覆盖原生行为
你可以在 MyContext 上添加方法(比如 GetUser()、LogError()),但绝不能重命名或改变签名与原生 iris.Context 冲突的方法(如 JSON()、StatusCode()、HTML())。
否则会导致中间件行为异常:例如某个中间件调用 ctx.StatusCode(401),结果触发了你重写的版本,而该版本没调用 ctx.ResponseWriter().WriteHeader(),响应就卡住。
- 新增方法名建议加前缀(如
MyJSON()、SafeParam())或限定领域(如AuthUser()) - 若需修改原生方法逻辑(如统一加 header),应通过中间件 +
ctx.Header().Set()实现,而非覆盖方法 - 所有自定义方法内部调用原生方法时,必须用
c.Context.JSON(...)显式指定,防止无限递归
注意生命周期和 Pool 复用问题
自定义上下文对象本身不进 sync.Pool,但其内嵌的 iris.Context 会。这意味着:每次请求你 new 出来的 *MyContext 是全新实例,但里面的 Context 字段可能复用了旧对象的状态(比如未清空的 Values、Params)。
最易忽略的是 ctx.Values().Set() 存的数据,在下一次复用时仍存在——如果你在 WrapRouter 里不做清理,就会出现 A 请求写入的值被 B 请求读到。
- 务必在
WrapRouter中调用ctx.Reset()或手动清空ctx.Values()和ctx.Params() - 不要在自定义结构体里缓存 request body、form data 等一次性数据,它们可能已被消费过
- 如果依赖
ctx.HandlerName()或ctx.GetCurrentRoute(),确保WrapRouter调用时机在路由匹配之后(Iris 默认满足,但自定义 router 逻辑可能打乱顺序)











