Gin|Gin 如何动态生成模型 swagger 文档

在做 API 接口开发时, 一般会统一 API 返回格式, 例如

{ "code": 200, "data": { //xxxxx //xxxxx }, "message": "OK" }

在后端代码定义中, 也会定义一个结构体来对应这种结构, 并且, 由于 data 字段里的数据是未知的(与具体业务相关), 所以会定义一个 interface 来接收
type ApiResponse struct { Code int`json:"code"` Msgstring`json:"message"` Data interface{} `json:"data"` }

然后根据具体业务响应, 向 data 传入不同的模型, 比如
c.JSON(200, ApiResponse{200, "OK", User})

但是这里有个很大的问题, swagger 文档中, 这个接口的返回值该怎么定义?
// @Summary 获取用户信息 // ... // ... // @Success 200 {object} ApiResponse "ok" func GetUser(c *gin.Context) { xxxx }

如果这样定义, 生成的文档会是下面这样, 因为原始 ApiResponse 就是一个 interface, 所以是空
Gin|Gin 如何动态生成模型 swagger 文档
文章图片

但是这样的文档写出来就没什么意义了, 大多数的做法就是会专门定义一个用于 swagger 显示的结构体, 类似这样
type UserResponse struct { Code int`json:"code"` Msgstring`json:"message"` Data User`json:"data"` }

虽然效果有了, 但是这样无疑增加了巨多的工作量, 让写代码变得索然无味, 翻看 swaggo/swag 的文档, 发现支持了替换字段的方式, 可以完美解决现在这种问题, 效果如下
Gin|Gin 如何动态生成模型 swagger 文档
文章图片

【Gin|Gin 如何动态生成模型 swagger 文档】下面是测试代码
package mainimport ( "net/http" "strconv" "github.com/gin-gonic/gin" )// @title Swagger Example API // @version 1.0 // @description This is a sample server Petstore server. // @termsOfService http://swagger.io/terms/// @contact.name API Support // @contact.url http://www.swagger.io/support // @contact.email support@swagger.io// @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html// @host petstore.swagger.io // @BasePath /v2 func main() { r := gin.New() r.GET("/user/:id", GetUser) }// @Summary 获取用户信息 // @Description get User by ID // @ID get-user-by-id // @Acceptjson // @Producejson // @Paramidpathinttrue"用户 id" // @Success 200 {object} ApiResponse{data=https://www.it610.com/article/User}"ok" // @Router /user/{id} [get] func GetUser(c *gin.Context) { resp := new(ApiResponse) paramID := c.Param("id") uid, _ := strconv.Atoi(paramID) user := User{ ID:uid, Name: "张三", } resp.Code = 200 resp.Msg = "OK" resp.Data = https://www.it610.com/article/user c.JSON(http.StatusOK, resp) }type User struct { IDint`json:"id"` Name string `json:"name"` }type ApiResponse struct { Code int`json:"code"` Msgstring`json:"message"` Data interface{} `json:"data"` }

    推荐阅读