请求/响应/错误码设计
最后更新于: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.", "给您带来的不便,深感抱歉,请稍后再试")
)
```
';