什么意思?
- 在开发时,我们需要统一对外输出
json
信息,场景信息如下:
{
"code": 0,
"message": "message",
}
普通操作
- 在 gin 中,我们需要使用
c.JSON
或 c.AsciiJSON
函数进行 JSON 输出,如下
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
r := gin.Default()
r.GET("/test", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"code": 0,
"message": "正常",
"dataset": gin.H{
"name": "测试接口"
},
})
})
}
要解决的问题
- 在上面代码例子中,我们可以看到,如果这样写,那么每次都需要写 balabala 这么多代码
- 所以就得简化代码,我们可以怎么样简化呢?
code
和 message
这是最基本字段,无论接口是错误还是正确,这两个字段都必须要输出
- 其他字段,按需返回,毕竟真实开发过程中,不止有一个
dataset
自定义字段放在第一层
解决问题
- 既然我们要简化,那就得封装
- 首先我们需要区分接口错误输出、正确输出,得封装成2个方法
SuccessResponse
ErrorResponse
为什么需要区分呢?
- 首先,正常开发需求中,
code
、message
大多数时候是默认值,只有在特定接口返回特定信息
- 但是,Go 不支持默认值写法,所以经过我的一顿操作,代码如下:
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func SuccessResponse(data ...interface{}) gin.H {
code := 0
message := "成功"
params := gin.H{}
for _, value := range data {
switch value.(type) {
case int:
code = value.(int)
case string:
message = value.(string)
case gin.H:
params = value.(gin.H)
}
}
return Response(code, message, params)
}
func ErrorResponse(data ...interface{}) gin.H {
code := -1
message := "错误"
params := gin.H{}
for _, value := range data {
switch value.(type) {
case int:
code = value.(int)
case string:
message = value.(string)
case gin.H:
params = value.(gin.H)
}
}
return Response(code, message, params)
}
func Response(code int, message string, params gin.H) gin.H {
response := gin.H{
"code": code,
"message": message,
}
for index, value := range params {
response[index] = value
}
return response
}
func main() {
r := gin.Default()
r.GET("/1", func(c *gin.Context) {
c.JSON(http.StatusOK, SuccessResponse(0))
})
r.GET("/2", func(c *gin.Context) {
c.JSON(http.StatusOK, SuccessResponse("这是2接口"))
})
r.GET("/3", func(c *gin.Context) {
c.JSON(http.StatusOK, SuccessResponse(gin.H{
"dataset": gin.H{
"goods": []int{123,456},
},
}))
})
r.GET("/4", func(c *gin.Context) {
c.JSON(http.StatusOK, SuccessResponse(0, gin.H{
"dataset": gin.H{
"goods": []int{123,456},
},
}))
})
r.GET("/5", func(c *gin.Context) {
c.JSON(http.StatusOK, SuccessResponse("这是5接口", gin.H{
"dataset": gin.H{
"goods": []int{123,456},
},
}))
})
r.GET("/6", func(c *gin.Context) {
c.JSON(http.StatusOK, SuccessResponse(2, "这是6接口", gin.H{
"dataset": gin.H{
"goods": []int{123,456},
},
}))
})
_ = r.Run()
}
代码分析
- 通过上面代码,可以看到,通过声明参数为
interface{}
类型,实现了对参数的动态变化,通过封装方法,内置了默认返回值
- 可以自由灵活的进行传参,简化代码输出自己想要的数据(想要凑代码行数的请忽略此文章)