Go-Zero项目中通过定义Response结构体、HttpResult函数和CodeError错误类型实现HTTP响应统一格式,避免前端解析异常;需严格使用uint32码、errors.Cause判断错误、禁用httpx.OkJson等原生方法。

在Go-Zero项目中实现统一的HTTP响应格式,避免每个handler手动拼接code/message/data字段,防止前端因返回结构不一致导致解析失败或空指针异常。
定义统一响应结构体
在项目根目录下新建 common/response/response.go 文件,声明标准返回结构。
创建 Response 结构体,字段必须导出且带 JSON 标签:Code 为 uint32 类型(兼容 gRPC status.Code),Message 为 string,Data 为 interface{}。
这一步不能用 int 代替 uint32——【gRPC 错误码映射依赖 uint32,用 int 会导致 httpx.WriteJson 序列化后 code 值异常】。
结构体无需实现任何接口,仅作数据载体使用。
封装 HTTP 返回函数
在同一个 response.go 文件中,添加 HttpResult 函数,接收 *http.Request、http.ResponseWriter、响应数据 resp 和 error。
函数内部先判断 err 是否为 nil:为 nil 时构造成功响应,Code=0、Message="success"、Data=resp;非 nil 时进入错误分支。
错误分支需调用 errors.Cause(err) 获取原始错误,再依次判断是否为 *xerr.CodeError 或 gRPC status.Error——【跳过 Cause 直接断言会导致自定义错误被忽略,始终返回 500】。
无论哪种错误类型,最终都调用 logx.WithContext(r.Context()).Errorf 记录完整错误栈,并用 httpx.WriteJson 返回标准化错误 JSON。
定义可透传的业务错误类型
在 common/xerr/errors.go 中定义 CodeError 结构体,含 errCode uint32 和 errMsg string 两个字段。
实现 GetErrCode() 和 GetErrMsg() 方法,确保前端能拿到精确的业务错误码和提示语。
必须实现 Error() 方法,否则 go-zero 的中间件无法识别该错误类型。
提供 NewErrCodeMsg 工厂函数,方便业务层快速构造错误:比如 loginLogic 中校验失败可直接 return xerr.NewErrCodeMsg(1001, "用户名或密码错误")。
在 handler 中使用统一返回
第一步:在对应 service/api/handler/xxxhandler.go 的 logic 调用处捕获 error。
第二步:将 logic 返回的 resp 和 err 一起传入 HttpResult(r, w, resp, err)。
第三步:删除所有原本的 httpx.OkJson / httpx.Error 调用——【goctl v1.4.2 生成的 handler 默认用 httpx.OkJsonCtx,若混用会破坏统一结构】。
这一步操作起来很简单,直接替换两行代码即可,但必须确保整个服务所有 handler 都走同一入口函数。


















