自定义Respone好处
在写接口的时候,我们通过都需要将前端小伙伴发给我们的请求进行校验和返回数据,如果是正确的请求参数,那么也符合我们的校验,则需要返回数据给他们,并且给予提示;反之,如果请求是不符合的我们则需要基于提示用户或让前端小伙伴进行做出对应的修改,比如:参数类型错误、字段错误等信息回返给前端的小伙伴进行做出对应的修改。这时候有些提示信息则会重复,一直写重复的提示难免会有点繁琐,那么作为后端开发的小伙伴们可以选择对于这些response
进行封装一些方法,减少所谓的重复性代码,也可以提高我们自己的代码可阅读性和质量。本文结合了上一篇文章中的zap封装的日志开发进行完成本次的例子,可以点击访问Go开发中配置一个Logger日志的功能实现(结合zap日志库)
编码
下列的编码仅供参考,可以根据自己喜欢的方式进行定义,或者根据自己的业务场景进行编码
定义返回格式
首先我们肯定是需要定义格式,到时候把这个格式告诉前端小伙伴,他们就可以根据这个格式也可以封装一些方法,提高整体项目的开发效率和代码阅读性,通常前后端的数据交互都是以json
返回给前端的,下面我们也以json方式进行编码。
{
"code": 1001, // 错误码
"msg": "xxx", // 提示信息
”data“: {}, // 存放数据
}
编写struct类型 response.go
type ResponseData struct {
Code ResCode `json:"code"`
Msg interface{} `json:"msg"`
Data interface{} `json:"data"`
}
定义code的返回内容 code.go
type ResCode int64
const (
CodeSuccess ResCode = 1000 + iota
CodeInvalidParam
CodeUserExist
CodeUserNotExist
CodeInvalidPassword
CodeServerBusy
)
var codeMsgMap = map[ResCode]string{
CodeSuccess: "success",
CodeInvalidParam: "请求参数错误",
CodeUserExist: "用户已存在",
CodeUserNotExist: "用户不存在",
CodeInvalidPassword: "用户名或密码错误",
CodeServerBusy: "服务繁忙",
}
func (c ResCode) Msg() string {
msg, ok := codeMsgMap[c]
if !ok {
msg = codeMsgMap[CodeServerBusy]
}
return msg
}
编写返回方法 response.go
func ResponseError(c *gin.Context, code ResCode) {
c.JSON(http.StatusOK, &ResponseData{
Code: code,
Msg: code.Msg(),
Data: nil,
})
}
/*
// 或者也可以这样
func ResponseError(c *gin.Context, code ResCode) {
responseData := &ResponseData{
Code: code,
Msg: code.Msg(),
Data: nil,
}
c.JSON(http.StatusOK,responseData )
}
*/
// ResponseSuccess 返回成功
func ResponseSuccess(c *gin.Context, data interface{}) {
c.JSON(http.StatusOK, &ResponseData{
Code: CodeSuccess,
Msg: CodeSuccess.Msg(),
Data: data,
})
}
// ResponseErrorWithMsg 自定义返回内容
func ResponseErrorWithMsg(c *gin.Context, code ResCode, msg interface{}) {
c.JSON(http.StatusOK, &ResponseData{
Code: code,
Msg: msg,
Data: nil,
})
}
写好以后的使用方法
以login登录方法为例
func LoginHandle(c *gin.Context) {
p := new(models.ParamsLogin)
if err := c.ShouldBindJSON(p); err != nil {
// 请求参数有无,直接返回相应
zap.L().Error("Login with invalid 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 with fail", zap.String("username", p.Username), zap.Error(err))
if errors.Is(err, mysql.ErrorUserNotExist) {
ResponseError(c, CodeUserNotExist)
return
}
ResponseError(c, CodeInvalidParam)
return
}
ResponseSuccess(c, nil)
}
最后的成功展示
使用postman或者apifox进行测试一下成功
和失败
的返回结果吧!
- 成功的返回请求
- 失败的返回请求