定义统一响应体(包含code,msg,data和WithData/WithMsg方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package config

import (
"encoding/json"
"net/http"
)

var (
// OK
OK = response(http.StatusOK, "ok")
)

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,
}
}

使用

1
2
3
4
func load(c *gin.Context) error {
c.JSON(http.StatusOK, config.OK.WithData(...))
return nil
}

定义响应错误的结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package config

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

// APIException 错误的结构体,继承Response
type APIException struct {
*Response
}

// 实现error接口
func (e *APIException) Error() string {
return e.Msg
}

func newAPIException(code int, msg string) *APIException {
return &APIException{
&Response{
Code: code,
Msg: msg,
},
}
}
// 这里单独定义一个和gin HandlerFunc相同的type,供后续使用
type HandlerFunc func(c *gin.Context) error

异常处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package config

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

// Wrapper 统一异常处理
func Wrapper(handler HandlerFunc) func(c *gin.Context) {
return func(c *gin.Context) {
var (
err error
)
err = handler(c)
if err != nil {
var apiException *APIException
// APIException异常
if h, ok := err.(*APIException); ok {
apiException = h
} else if e, ok := err.(error); ok {
if gin.Mode() == "debug" {
// 错误
apiException = ServerErrorWithMsg(e.Error())
} else {
// 未知错误
apiException = UnknownError(e.Error())
}
} else {
apiException = ServerError()
}
c.JSON(http.StatusOK, apiException)
return
}
}
}

// ServerError 500 错误处理
func ServerError() *APIException {
return newAPIException(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}

// ServerErrorWithMsg 500 错误处理
func ServerErrorWithMsg(msg string) *APIException {
return newAPIException(http.StatusInternalServerError, msg)
}

// NotFound 404 错误
func NotFound() *APIException {
return newAPIException(http.StatusNotFound, http.StatusText(http.StatusNotFound))
}

// UnknownError 未知错误
func UnknownError(message string) *APIException {
return newAPIException(http.StatusForbidden, message)
}

// ParameterError 参数错误
func ParameterError(message string) *APIException {
return newAPIException(http.StatusBadRequest, message)
}

// HandleNotFound method/request not found处理
func HandleNotFound(c *gin.Context) {
handleErr := NotFound()
c.JSON(handleErr.Code, handleErr)
}

使用

1
2
3
4
5
6
func Route(e *gin.RouterGroup) {
e.POST("/", config.Wrapper(load))
}

func load(c *gin.Context) error {
}