自定义业务状态码

业务状态码和HTTP状态码

  • 业务状态码:在 REST 接口设计规范中,我们通常都会被引导为这里的 Code 应该是 HTTP 协议状态码 200,404 或者 501 等
  • HTTP状态码:HTTP 请求状态码是 HTTP 协议的一部分,用于表明 HTTP 响应状态

How to prepare code

1. Code业务状态码封装

package controller

type ResCode int64
const (
CodeSuccess ResCode=1000+iota
CodeInvalidParam
CodeUserExist
CodeUserNotExist
CodeInvalidPassword
CodeServeBusy
)
var codeMsgMap=map[ResCode]string{
CodeSuccess: "success",
CodeInvalidParam:"请求参数错误",
CodeUserExist: "用户已存在",
CodeUserNotExist:"用户不存在",
CodeInvalidPassword:"用户名或者密码错误",
CodeServeBusy:"服务繁忙",
}

func (c ResCode) Msg() string{
msg,ok:=codeMsgMap[c]
if !ok{
msg=codeMsgMap[CodeServeBusy]
}
return msg
}

2. 封装业务方法

package controller

import (
"github.com/gin-gonic/gin"
"net/http"
)

type ResponseData struct {
Code ResCode `json:"code"`
Msg interface{} `json:"msg"`
Data interface{} `json:"data"`
}

func ResponseError(c *gin.Context, code ResCode) {
c.JSON(http.StatusOK, &ResponseData{
Code: code,
Msg: code.Msg(),
Data: nil,
})
}
func ResponseErrorWithMsg(c *gin.Context, code ResCode, msg interface{}) {
c.JSON(http.StatusOK, &ResponseData{
Code: code,
Msg: msg,
Data: nil,
})
}

func ResponseSuccess(c *gin.Context, data interface{}) {
c.JSON(http.StatusOK, &ResponseData{
Code: CodeSuccess,
Msg: CodeSuccess.Msg(),
Data: data,
})
}

3. Dao层包装错误 Example


var (
ErrorUserExist = errors.New("用户已存在")
ErrorUserNotExist = errors.New("用户不存在")
ErrorInvalidPassword = errors.New("密码错误")
)

// CheckUserExist : 检查用户是否存在
func CheckUserExist(username string) (err error) {
sqlStr := `select count(user_id) from user where username=?`
var count int
if err := db.Get(&count, sqlStr, username); err != nil {
return err
}
if count > 0 {
return ErrorUserExist //使用全局错误定义
}
return
}

4. Use Example

// LoginHandler : 登录
func LoginHandler(c *gin.Context) {
p := new(models.ParamLogin)
if err := c.ShouldBindJSON(p); err != nil {
zap.L().Error("Login with valid param", zap.Error(err))
errs, ok := err.(validator.ValidationErrors)
if !ok {
ResponseError(c,CodeInvalidParam)
return
}
ResponseErrorWithMsg(c,CodeInvalidParam,removeTopStruct(errs.Translate(trans)))
return
}
if err := logic.Login(p); err != nil {
zap.L().Error("logic.Login failed", zap.String("username", p.Username), zap.Error(err))
if errors.Is(err, mysql.ErrorUserNotExist) {
ResponseError(c,CodeUserNotExist)
return
}
ResponseError(c,CodeInvalidPassword)
return
}
ResponseSuccess(c,nil)
}