ctx.JSON 是 Iris 返回 JSON 的唯一推荐方式,需手动配置字段标签(如 json:"name")、状态码(如 StatusCode(iris.StatusNotFound))、零值忽略(omitempty)及启用 Gzip 压缩(app.Use(iris.Compression))。

ctx.JSON 是 Iris 返回 JSON 的唯一推荐方式,但它不是“设了就完事”的黑盒——字段标签、状态码、时间格式、压缩控制全得手动管。
ctx.JSON 必须配合结构体 json 标签使用
Go 的 json 包只序列化首字母大写的导出字段,但默认输出是 PascalCase(如 Name → {"Name":"xxx"}),前端通常要小驼峰。不加 json 标签就等于放弃字段命名控制。
- 错误写法:
type User { Name string }→ 前端收到{"Name":"Alice"} - 正确写法:
type User { Name string `json:"name"` }→ 输出{"name":"Alice"} - 忽略零值:
Age int `json:"age,omitempty"`,当Age == 0时不出现该字段 - 嵌套、切片、指针都原生支持,无需额外配置
状态码必须显式设置,ctx.JSON 不会自动改
调用 ctx.JSON(iris.Map{"error": "not found"}) 默认返回 200 状态码,前端无法靠 HTTP 状态判断失败。这是最常被忽略的语义断裂点。
- ❌ 错误:
ctx.JSON(iris.Map{"error": "user not found"})→ 状态码仍是 200 - ✅ 正确:
ctx.StatusCode(iris.StatusNotFound); ctx.JSON(iris.Map{"error": "user not found"}) - 更稳妥:封装一个
writeError(ctx, code, msg)函数统一处理,避免漏设 - 注意:
ctx.JSON内部调用的是json.Marshal,如果传入值本身 Marshal 失败(比如含不可序列化字段),会直接 panic,务必确保输入结构体干净
大响应体建议启用 Gzip,但需客户端配合
ctx.JSON 本身不压缩,体积大的 JSON(比如列表页、导出数据)会明显拖慢传输。Iris 提供 iris.Compression 中间件,但生效有前提。
- 启用方式:
app.Use(iris.Compression),必须放在所有路由注册之前 - 触发条件:响应头含
Content-Type: application/json+ 请求头含Accept-Encoding: gzip - 小响应(
- 若只想压缩 API 路由:
api := app.Party("/api"); api.Use(iris.Compression)
time.Time 字段默认输出 RFC3339,不是 Unix 时间戳
结构体里直接放 CreatedAt time.Time 并打上 json:"created_at",前端拿到的是 "2026-10-09T10:30:00Z",不是数字时间戳,也不是 "2026-10-09 10:30:00"。硬解析会出错。
- 不改结构体时:前端用
new Date(str)解析即可,别用parseInt或正则截取 - 要转 Unix 时间戳:自定义
MarshalJSON方法,返回int64(t.Unix()) - 要 MySQL 格式:同上,返回
t.Format("2006-01-02 15:04:05") - 真正容易被忽略的是:这个行为和
json.Marshal完全一致,Iris 没做任何封装或覆盖


















