Beego 接口应优先用 ctx.JSON 自动序列化结构体,避免手动拼JSON或 this.Data["json"];需导出字段、慎用omitempty;统一错误结构并正确设HTTP状态码;务必 return 终止执行防重复响应;修改结构体后必须重启应用。

Beego 的接口数据返回不是靠手动拼 JSON 字符串,而是靠 Controller 内置的 JSON、JSONP、XML 等方法自动序列化结构体或 map,且默认启用 gob 编码缓存——这点常被忽略,导致开发时数据没变但返回旧值。
用 ctx.JSON 还是 this.Data["json"]?
Beego 1.12+ 推荐直接调用 ctx.JSON(context.Context 实例),它绕过 Beego 自带的模板渲染流程,更轻量、更可控;而老写法 this.Data["json"] = data; this.ServeJSON() 会触发额外的 render 流程,可能受 EnableRender 配置影响,还可能意外执行 Prepare 或 Finish 钩子。
-
ctx.JSON是最简路径:不走模板、不检查Data映射、不触发ServeJSON的额外逻辑 - 若需统一处理(如加全局字段、日志、错误包装),建议封装一个
writeJSON(ctx context.Context, v interface{}, code int)工具函数,而不是依赖ServeJSON -
this.ServeJSON()在开启EnableDocs时可能干扰 Swagger 注解解析,尤其当返回类型声明和实际结构不一致时
结构体字段导出与 JSON 标签控制
Beego 默认使用 Go 原生 json 包序列化,所以字段必须首字母大写(导出),否则不会出现在 JSON 中;同时要小心 omitempty 导致零值字段消失,前端可能因此报错。
- 空字符串
""、0、false、nil在含omitempty时会被跳过——调试时用curl -v看响应体,别只信前端 log - 时间字段推荐用
time.Time+json:"created_at,omitempty",并确保在app.conf中设置了TimeFormat = "2006-01-02T15:04:05Z",否则time.Time默认输出纳秒级数字 - 避免用
map[string]interface{}返回嵌套数据,易出类型混乱;优先定义明确结构体,便于 IDE 提示和后期加校验
返回错误时别只写 ctx.JSON(500, map[string]string{"error": "xxx"})
HTTP 状态码和错误结构不匹配是常见问题:比如业务校验失败应返回 400 或 422,而非一律 500;且 Beego 默认不设置 Content-Type: application/json,某些严格客户端(如 Axios with responseType: 'json')会解析失败。
- 显式调用
ctx.ResponseWriter.Header().Set("Content-Type", "application/json; charset=utf-8")是冗余的——ctx.JSON内部已设置,但ctx.WriteString不会 - 推荐统一错误响应结构:
type Resp struct { Code int `json:"code"` Msg string `json:"msg"` Data interface{} `json:"data,omitempty"` },再用ctx.JSON(statusCode, Resp{...}) - 数据库查询为空时,别返回
200 + null,应明确返回404并带提示,否则前端无法区分“查无结果”和“服务异常”
Beego 的 AutoRender 和 DisableRender 对接口的影响
Beego 默认开启 AutoRender = true,意味着即使你调用了 ctx.JSON,只要没显式中断执行流(如 return),后续代码仍会跑,并可能触发模板渲染,造成重复写 response 报错:http: multiple response.WriteHeader calls。
- 在 controller 方法末尾加
return是必须的——不是风格问题,是防止 panic - 若整个 controller 只做 API,可在
Init或Prepare中调用this.DisableRender(),这样即使漏了return也不会尝试渲染模板 -
DisableRender()不影响ctx.JSON,它只禁用this.TplName和this.ServeXXX类方法
最常被忽略的是:Beego 会在启动时缓存 controller 结构体的反射信息,如果你热更新代码但没重启进程,JSON 序列化行为可能和源码不一致——尤其是字段增删后,旧缓存仍试图序列化已删除字段,导致 panic 或静默丢数据。改完结构体,务必重启应用。











