请求/响应/错误码设计

最后更新于:2022-04-02 02:36:29

[TOC] > [参考](https://juejin.cn/post/7025223216473833486) ## 概述 server 层的代码 ``` type LoginService struct{} func (s *LoginService) Login(req *model.LoginReq) (*model.LoginRsp, result.Error) { if req.Username != "admin" || req.Password != "admin" { return nil, result.NewError(result.ErrCodeInvalidParameterUsernameOrPassword) } return &model.LoginRsp{ Token: uuid.New().String(), }, nil } ``` req和rsp都是简单的结构体 ``` type LoginReq struct { Username string `json:"username"` Password string `json:"password"` } type LoginRsp struct { Token string `json:"token"` } ```
error.go ``` import ( "errors" ) type Unwrap interface { Unwrap() error } type Error interface { error Unwrap ErrCode } // ErrorImpl 错误 type ErrorImpl struct { error ErrCode } // Unwrap 实现 Unwrap 接口 func (e ErrorImpl) Unwrap() error { return e.error } // WrapError 包装 error func WrapError(errCode ErrCode, err error) Error { return ErrorImpl{ error: err, ErrCode: errCode, } } // NewError 新建一个 Error func NewError(errCode ErrCode) Error { return ErrorImpl{ error: errors.New(errCode.Msg()), ErrCode: errCode, } } ```

error_code.go ``` // ErrCode 错误码 type ErrCode interface { Status() int // HTTP状态码 Code() string // 错误码 Msg() string // 错误消息 Advice() string // 建议处理方式 } // errCodeImpl 错误码实现 type errCodeImpl struct { status int code string msg string advice string } func (e errCodeImpl) Status() int { return e.status } func (e errCodeImpl) Code() string { return e.code } func (e errCodeImpl) Msg() string { return e.msg } func (e errCodeImpl) Advice() string { return e.advice } // newErrCode 新建一个错误码 func newErrCode(status int, code, msg, advice string) ErrCode { return errCodeImpl{ code: code, msg: msg, status: status, advice: advice, } } ```

gin_rsp.go ``` import ( "github.com/gin-gonic/gin" ) // Rsp 响应 type Rsp struct { Code string `json:"code,omitempty"` // 错误码 Msg string `json:"msg,omitempty"` // 消息 Data interface{} `json:"data,omitempty"` // 数据 } // Success 请求成功 func Success(c *gin.Context, data interface{}) { rsp(c, ErrCodeOK, data) } // Failure 请求失败 func Failure(c *gin.Context, errCode ErrCode) { rsp(c, errCode, nil) } // rsp 响应 func rsp(c *gin.Context, errCode ErrCode, data interface{}) { c.JSON(errCode.Status(), &Rsp{ Code: errCode.Code(), Msg: errCode.Advice(), Data: data, }) } ```

err_codes.go ``` var ( ErrCodeOK = newErrCode(http.StatusOK, "OK", "", "") ErrCodeInvalidParameter = newErrCode(http.StatusBadRequest, "InvalidParameter", "The required parameter is not valid.", "非法参数") ErrCodeInvalidParameterUsernameOrPassword = newErrCode(http.StatusBadRequest, "InvalidParameter.UsernameOrPassword", "The username or password is not valid.", "账号或密码错误") ErrCodeInternalError = newErrCode(http.StatusInternalServerError, "InternalError", "The request processing has failed due to some unknown error.", "给您带来的不便,深感抱歉,请稍后再试") ) ```

';