ctx.ReadJSON 是 Iris 中处理 JSON 请求最稳方式,需配合带 validate 标签的导出结构体实现自动绑定、类型转换与校验;裸用 map 或 json.Unmarshal 会丢失校验能力,且必须处理 content-type 和空 body 边界情况。

ctx.ReadJSON 是 Iris 中处理 POST/PUT 请求里 JSON 数据最稳的方式,它能自动绑定、类型转换和基础校验,但必须配合结构体 + validate 标签才真正可靠;裸用 map[string]interface{} 或直接 json.Unmarshal 会丢掉校验能力,也难统一错误响应。
定义带 validate 标签的结构体
结构体字段名、JSON key、校验规则三者要对齐。Iris 不强制要求字段首字母大写,但小写字段无法被 json 包序列化,所以必须大写;validate 标签语法和 go-playground/validator 完全一致:
-
json:"name"控制反序列化时的 key 映射,必须和前端传的字段名一致 -
validate:"required,min=2,max=20"在ReadJSON时触发,失败返回 error - 若需区分“未传”和“传了空字符串”,字符串字段用
*string,数字用*int - 嵌套结构体支持,比如
User struct { Profile *Profile `validate:"required"` }
示例:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
type CreateUserInput struct {
Name string `json:"name" validate:"required,min=2,max=20"`
Age int `json:"age" validate:"min=0,max=150"`
Email string `json:"email" validate:"required,email"`
}
在 handler 中调用 ctx.ReadJSON
别跳过 error 检查,且不要在出错后继续执行业务逻辑。Iris 不会自动返回 400,得自己处理:
- 用
if err := ctx.ReadJSON(&input); err != nil判断,err是validator.ValidationErrors类型 -
err.Error()返回类似"Key: 'CreateUserInput.Email' Error:Field validation for 'Email' failed on the 'email' tag",可直接用于日志或调试 - 生产环境建议用
validator.ValidationErrors.Translate(uni.Translator)做国际化,但简单项目直接返回iris.StatusBadRequest+ 错误摘要更轻量 - 不要用
ctx.ReadJSON(&map[string]interface{})——它绕过了所有结构体校验,等于放弃防线
注意 content-type 和空 body 边界情况
Iris 默认只接受 application/json,但前端可能发错类型,或发空 body(比如 curl -X POST http://x):
- 如果请求头没带
Content-Type: application/json,ReadJSON会返回"invalid content type, expecting 'application/json'" - 如果 body 为空或纯空白,
ReadJSON会返回"unexpected end of JSON input",不是 validator 错误,得单独判断 - 建议前置加一层中间件检查
ctx.GetContentType()是否包含"application/json",否则直接ctx.StatusCode(iris.StatusBadRequest) - 空 body 场景下,
ReadJSON不会 panic,但会返回 error,必须显式处理,不能假设结构体字段有默认值就安全
真正容易被忽略的是:校验失败后,很多人直接 return 却忘了设状态码,导致前端收到 200 + 空响应;还有人把 validate 标签写成 valid: 或漏掉引号,结果标签完全不生效——这种问题只能靠单元测试覆盖,光靠手动测很难发现。

















