响应结果封装之前
以Gin框架为例,在使用 gin 开发接口的时候,返回接口数据是这样写的。
import "github.com/gin-gonic/gin"
func main() {
engine := gin.Default()
//GET请求 http://localhost:8888/hello
engine.GET("/hello", func(c *gin.Context) {
//返回状态 + json对象(常用)
c.JSON(http.StatusOK, gin.H{
"code": 200,
"msg": "ok",
"data": nil,
})
})
engine.Run(":8888") // 监听并在 0.0.0.0:8888 上启动服务
}
弊端:这种写法 code、msg 都是在哪需要返回在哪定义,没有进行统一管理。
响应结果封装
package ginResult
import (
"encoding/json"
)
type Response struct {
Code int `json:"code"` // 错误码
Msg string `json:"msg"` // 错误描述
Data interface{
} `json:"data"` // 返回数据
}
// 自定义响应信息
func (res *Response) WithMsg(message string) Response {
return Response{
Code: res.Code,
Msg: message,
Data: res.Data,
}
}
// 追加响应数据
func (res *Response) WithData(data interface{
}) Response {
return Response{
Code: res.Code,
Msg: res.Msg,
Data: data,
}
}
// ToString 返回 JSON 格式的错误详情
func (res *Response) ToString() string {
err := &struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data interface{
} `json:"data"`
}{
Code: res.Code,
Msg: res.Msg,
Data: res.Data,
}
raw, _ := json.Marshal(err)
return string(raw)
}
// 构造函数
func response(code int, msg string) *Response {
return &Response{
Code: code,
Msg: msg,
Data: nil,
}
}
统一管理错误码,方便管理
package ginResult
// 错误码规则:
// (1) 错误码需为 > 0 的数;
//
// (2) 错误码为 5 位数:
// ----------------------------------------------------------
// 第1位 2、3位 4、5位
// ----------------------------------------------------------
// 服务级错误码 模块级错误码 具体错误码
// ----------------------------------------------------------
var (
// OK
OK = response(200, "ok") // 通用成功
Err = response(500, "") // 通用错误
// 服务级错误码
ErrParam = response(10001, "参数有误")
ErrSignParam = response(10002, "签名参数有误")
// 模块级错误码 - 用户模块
ErrUserService = response(20100, "用户服务异常")
ErrUserPhone = response(20101, "用户手机号不合法")
ErrUserCaptcha = response(20102, "用户验证码有误")
// 库存模块
ErrOrderService = response(20200, "订单服务异常")
ErrOrderOutTime = response(20201, "订单超时")
// ......
)
响应结果封装之后
import (
"github.com/gin-gonic/gin"
result "go_basis/26_Gin框架/ginResult"
"net/http"
)
func main() {
engine := gin.Default()
engine.GET("/ok", func(c *gin.Context) {
c.JSON(http.StatusOK, result.OK)
})
engine.GET("/data", func(c *gin.Context) {
res := struct {
Name string `json:"name"`
Age int `json:"age"`
Email string `json:"email"`
}{
Name: "小明",
Age: 18,
Email: "[email protected]",
}
c.JSON(http.StatusOK, result.OK.WithData(res))
})
engine.GET("/common/err", func(c *gin.Context) {
c.JSON(http.StatusInternalServerError, result.Err.WithMsg("通用错误"))
})
engine.GET("/specified/err", func(c *gin.Context) {
c.JSON(http.StatusInternalServerError, result.ErrOrderOutTime)
})
engine.Run(":8888") // 监听并在 0.0.0.0:8888 上启动服务
}
经过简单的封装,既能实现错误响应的统一管理,又能方便接口的编写