iris.Context.QueryArgs() 返回 Args 类型需调用方法提取,不能直接断言;查询参数应优先用 ctx.FormValue();DB 操作应放在 Service 层并通过中间件注入 ctx.Values();time.Time 序列化需注意驱动差异和 struct tag。

iris.Context.QueryArgs() 不能直接获取 URL 查询参数?
不是不能,而是它返回的是 Args 类型,不是 map 或 string,必须用方法提取。常见错误是直接打印或类型断言失败,导致空值或 panic。
- 用
ctx.URLParam("key")获取路径参数(如/user/:id中的id) - 用
ctx.URLParamTrim("key")自动去除首尾空格 - 查询参数(
?name=foo&age=25)要用ctx.FormValue("name")或ctx.Request().URL.Query().Get("name") -
ctx.FormValue同时兼容 POST 表单和 URL 查询,更推荐;Query().Get仅限 GET 查询,但可调用Query().All()拿全部键值对
数据库查询逻辑该放在 Controller 还是 Service 层?
Iris 本身不强制分层,但把 db.QueryRow、db.Select 等操作硬写在 handler 里,会导致测试难、复用差、事务失控。
- Handler(即
iris.Handler函数)只做三件事:解析输入、调用 service、构造响应 - Service 层接收结构体参数(如
GetUserInput{ID: 123}),返回业务结构体或 error,不碰iris.Context - DB 实例建议通过依赖注入传入 service,而不是在 handler 里
sql.Open后直接传指针——连接池复用和生命周期管理会出问题 - 如果用 GORM,注意
gorm.Model(&User{}).Where(...).First()返回的是*gorm.DB,要接Error判断,不是直接判err != nil
用 iris.New().ConfigureContainer() 注入数据库实例后,为什么 handler 里还是 nil?
因为 ConfigureContainer 是为 Iris 的 DI 容器配置绑定,但 handler 函数默认不参与依赖注入——你写的 func(ctx iris.Context) 是纯函数,容器不会自动塞参数进去。
- 必须改用
handler := app.Party("/api").Handle("GET", "/users", myHandler)形式,并确保myHandler是通过app.ConfigureContainer注册过的类型(如*UserService) - 更简单的方式:在启动时把 DB 实例存进
app.Logger()之外的全局变量,或挂到app.ContextPool的Reset回调里(不推荐) - 真正推荐的做法:用
app.UseRouter+ 自定义中间件把 DB 注入到ctx.Values(),然后 handler 里用ctx.Values().Get("db")取——但要注意类型断言和并发安全
JSON 查询结果返回时时间字段变成数字或空字符串?
Go 的 time.Time 默认 JSON 序列化为 RFC3339 字符串,但如果你用了 github.com/lib/pq 或 github.com/go-sql-driver/mysql,驱动可能把 TIMESTAMP 映射成 time.Time,而 struct tag 写错就会失效。
- 确保结构体字段有
json:"created_at"和db:"created_at"tag - 如果数据库存的是秒级时间戳(int64),别用
time.Time接收,否则反序列化失败;改用int64或自定义类型实现UnmarshalJSON - Iris 默认用 Go 标准库
json.Marshal,不支持omitempty对零值 time 的过滤——time.Time{}会被序列化为"0001-01-01T00:00:00Z",需提前判断并置空
time.Time 在不同驱动下的行为差异。


















