Iris 需手动集成 mongo-go-driver,启动时用 context.WithTimeout 建立全局复用的 mongo.Client 并 Ping 验证,退出前 Disconnect;handler 中通过闭包或 DI 传入预建的 mongo.Collection,所有 DB 操作必须使用请求上下文。

iris 框架本身不内置 MongoDB 驱动,整合必须靠 Go 官方 mongo-go-driver 手动接入。没有“开箱即用”的 app.UseMongoDB() 这种东西,硬连才是常态。
怎么在 Iris 启动时建立并复用 MongoDB 连接
Go 的 MongoDB 客户端(mongo-go-driver)是线程安全的,*mongo.Client 实例应全局复用,不能每次请求都 mongo.Connect()。Iris 的 app 实例生命周期长,适合挂载连接对象。
- 在
main()里调用mongo.Connect()获取*mongo.Client,设为包级变量或通过app.ConfigureContainer()注入(v12.2.11+ 支持) - 务必设置上下文超时,例如
context.WithTimeout(context.Background(), 10*time.Second),避免启动卡死 - 连接后要调用
client.Ping()主动验证,否则错误会延迟到首次查询才暴露 - 别忘了在程序退出前调用
client.Disconnect(),虽然 Iris 没提供优雅关机钩子,得自己监听os.Interrupt
路由 handler 中怎么安全获取 collection 实例
不要在每个 handler 里重复写 client.Database("xxx").Collection("yyy") —— 这只是轻量对象构造,但频繁调用易出错、难维护。推荐提前建好,挂到 app 或传入闭包。
- 初始化时就创建好
*mongo.Collection:irisCollection := db.Collection("iris") - 用闭包封装 handler,把 collection 当参数传进去:
app.Get("/data", getDataHandler(irisCollection)) - 避免用
iris.Context.Values().Set()存 collection —— 值类型不安全,且容易被中间件覆盖 - 如果要用依赖注入风格,可借助
app.ConfigureContainer()注册*mongo.Collection类型,再在 handler 签名中声明接收(需启用 DI 支持)
常见错误:context 超时没传进 database 操作
MongoDB 的所有操作(Find、InsertOne、UpdateOne)都要求传 context.Context。直接传 context.Background() 会导致无法响应 HTTP 请求取消,还可能拖垮连接池。
- 必须从
ctx := iris.Context.Request().Context()拿请求上下文,再必要时加超时(如context.WithTimeout(ctx, 5*time.Second)) - 错误写法:
collection.Find(context.Background(), filter)—— 这会让数据库操作完全脱离 HTTP 生命周期 - 注意
mongo.FindOptions和context是两个东西,别混淆;context是第一个参数,不是 options 里的字段 - 如果 handler 返回前没消费完 cursor(比如忘了
cursor.All()或循环Next()),连接不会释放,久而久之耗尽
Iris 中间件里怎么统一处理 MongoDB 错误
数据库错误(连接断开、权限不足、超时)往往结构相似,适合在中间件里拦截并转成统一 JSON 响应。但注意:不是所有错误都该吞掉。
- 只对
mongo.IsConnectionFailedError()、mongo.IsTimeoutError()、mongo.IsDuplicateKeyError()等明确分类做处理 - 别用
strings.Contains(err.Error(), "connection refused")这种脆弱匹配 —— 驱动版本一变就失效 - 中间件里用
ctx.Next()后检查ctx.Response().StatusCode()是否为 0,再判断是否需要重写响应体 - 真实项目建议配合
logrus或zerolog记录原始 error,仅向客户端返回脱敏信息(如{"error": "service unavailable"})
WriteConcern)、事务支持这些细节,Iris 不参与控制 —— 全由 mongo-go-driver 的 options.ClientOptions 决定。别指望框架替你兜底。


















