返回码的方案对比和思考
前言
一般我们定义 Restful 接口返回码,常见的就是 const 定义 code , StatusToText() 来实现定义 msg, 在封装1 ~ 2个返回方法(success、error)就可以实现,只是突然想到这样设计是违反开闭原则的,如果要新增错误码就需要同步修改 StatusToText(),思来想去可以使用 工厂模式来实现。
示例
方案 1
const (Success errorCode = 200Failed errorCode = 500ParamError errorCode = 400NotFound errorCode = 404UnAuthorized errorCode = 401
)func StatusText(code errorCode) string {switch code {case Success:return "成功"case Failed:return "系统异常"case ParamError:return "参数错误"case NotFound:return "记录不存在"case UnAuthorized:return "未授权"default:return ""}
}
方案 2
var (Success = newError(0, "ok")ParamError = newError(400, "Bad Request")UnAuthorized = newError(401, "Unauthorized")NotFound = newError(404, "Not Found")Failed = newError(500, "Internal Server Error")
)type Error struct {Code intMessage string
}var errorCodeMap = map[error]int{}func newError(code int, msg string) error {err := errors.New(msg)errorCodeMap[err] = codereturn err
}
func (e Error) Error() string {return e.Message
}
封装方法
方案 1
func Success(ctx *gin.Context, msg string, data interface{}) {ctx.JSON(http.StatusOK, gin.H{"code": Success,"msg": msg,"data": data})
}func Error(ctx *gin.Context, httpCode, code errorCode, msg string) {ctx.AbortWithStatusJSON(httpCode, gin.H{"code": code,"msg": StatusText(code),"data": struct{}{},})
}
方案 2
type Response struct {Code int `json:"code"`Message string `json:"msg"`Data interface{} `json:"data"`
}func HandleSuccess(ctx *gin.Context, data interface{}) {if data == nil {data = map[string]interface{}{}}resp := Response{Code: errorCodeMap[ErrSuccess], Message: ErrSuccess.Error(), Data: data}if _, ok := errorCodeMap[ErrSuccess]; !ok {resp = Response{Code: 0, Message: "", Data: data}}ctx.JSON(http.StatusOK, resp)
}func HandleError(ctx *gin.Context, httpCode int, err error, data interface{}) {if _, ok := errorCodeMap[err]; !ok {ctx.JSON(httpCode, Response{Code: errorCodeMap[err], Message: err.Error(), Data: struct{}{}})} else {ctx.JSON(httpCode, Response{Code: 500, Message: "unknown error", Data: struct{}{}})}
}
总结
方案 1 :代码清晰直观,简单易读,违背开闭原则。
方案 2: 符合开闭原则,更适合拓展,具备上下文能力。
方案 | 简单接口 | 复杂业务 | 错误码规范 | 扩展性 | 兼容 error 接口 |
---|---|---|---|---|---|
方案 1 | 👍 | ❌ | 👍 | ❌ | ❌ |
方案 2 | ❌ | 👍 | 👍 | 👍 | 👍 |