响应输出与统一返回:DefaultHandlerResponse 与自定义

结论:GoFrame v2 推荐 handler 只 return (res, err),由 MiddlewareHandlerResponse 中间件统一包装为 {code, message, data}(对应 ghttp.DefaultHandlerResponse);需要自定义结构时替换该中间件即可,不要在业务代码里到处手写 JSON。

一、默认统一返回

  • 成功:{"code":0,"message":"OK","data":...}(message 文案以版本实现为准)。
  • 失败:业务层返回 error,中间件提取 gerror/gcode 的 code 与 message,data 为空。
  • 手动输出场景(文件下载、第三方回调、特殊格式)才用 r.Response.Write/WriteJson/WriteJsonExit。

二、自定义返回结构

自定义响应体的标准做法:写一个中间件,Next 之后读取 Handler 结果与错误,按自己的 Resp 结构输出,再全局或分组替换默认中间件。

代码示例

// 默认统一返回
s.Group("/", func(g *ghttp.RouterGroup) {
    g.Middleware(ghttp.MiddlewareHandlerResponse)
    g.Bind(UserController)
})
// 请求结果形如:{"code":0,"message":"OK","data":{...}}

// 自定义统一返回(骨架)
type Resp struct {
    Code int         `json:"code"`
    Msg  string      `json:"message"`
    Data interface{} `json:"data,omitempty"`
}

func MiddlewareResp(r *ghttp.Request) {
    r.Middleware.Next()
    if err := r.GetError(); err != nil {
        r.Response.WriteJsonExit(Resp{Code: -1, Msg: err.Error()})
        return
    }
    r.Response.WriteJsonExit(Resp{Code: 0, Data: r.GetHandlerResponse()})
}

常见追问 / 记忆点

  • 追问:错误码从哪来?→ 业务 error 若由 gerror.NewCode 构造则携带 gcode;未携带时框架给默认错误码(以官方实现为准)。
  • 追问:如何让前端拿到“业务失败也算 200”?→ 保持 HTTP 200 + body code 字段即可,由统一返回中间件保证结构稳定。
  • 记忆点:业务只 return res/err,包装交给中间件;改结构就换中间件,别改每个 handler。
笔记加载中…