Gin 如何動態生成模型 swagger 文檔


在做 API 接口開發時, 一般會統一 API 返回格式, 例如

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

在后端代碼定義中, 也會定義一個結構體來對應這種結構, 並且, 由於 data 字段里的數據是未知的(與具體業務相關), 所以會定義一個 interface 來接收

type ApiResponse struct {
	Code int         `json:"code"`
	Msg  string      `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, 所以是空

但是這樣的文檔寫出來就沒什么意義了, 大多數的做法就是會專門定義一個用於 swagger 顯示的結構體, 類似這樣

type UserResponse struct {
	Code int         `json:"code"`
	Msg  string      `json:"message"`
	Data User        `json:"data"`
}

雖然效果有了, 但是這樣無疑增加了巨多的工作量, 讓寫代碼變得索然無味, 翻看 swaggo/swag 的文檔, 發現支持了替換字段的方式, 可以完美解決現在這種問題, 效果如下

下面是測試代碼

package main

import (
	"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
// @Accept  json
// @Produce  json
// @Param   id      path   int     true  "用戶 id"
// @Success 200 {object} ApiResponse{data=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 = user
	c.JSON(http.StatusOK, resp)
}

type User struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

type ApiResponse struct {
	Code int         `json:"code"`
	Msg  string      `json:"message"`
	Data interface{} `json:"data"`
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM