macos Gin 安装 Swagger 接口文档

427 阅读3分钟

1. 安装 swag 工具

go install github.com/swaggo/swag/cmd/swag@latest

确保 swag 工具位于你的 PATH 中:

export PATH=$PATH:$GOPATH/bin

2. 安装 gin-swaggerswagger-files

go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files

3. 初始化 Gin 项目

创建一个新的 Go 项目并初始化 Gin:

mkdir myproject
cd myproject

go mod init myproject
go get github.com/gin-gonic/gin

4. 添加 Swagger 注释

在你的 Go 文件中添加 Swagger 注释。这是一个简单的示例:
package main

import (
    "github.com/gin-gonic/gin"
    "github.com/swaggo/gin-swagger"
    "github.com/swaggo/files"
    _ "myproject/docs"
    "net/http"
)

// @title Swagger Example API
// @version 1.0
// @description This is a sample server.
// @termsOfService http://swagger.io/terms/

// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io

// @host localhost:8080
// @BasePath /

func main() {
    r := gin.Default()
    // swagger 路由
    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

    r.GET("/ping", func(c *gin.Context) {
        c.JSON(http.StatusOK, gin.H{
            "message": "pong",
        })
    })

    r.Run() // r.Run() 方法中没传参,默认端口号为8080
}

5. 生成 Swagger 文档

在项目根目录运行 swag init 命令生成 Swagger 文档:

swag init
成功后将会下项目根目录下生成 docs 文件夹,里面包含 3 个文件

image.png

6. 运行项目

go run main.go

7. 访问 Swagger UI

打开浏览器,访问以下 URL:

需保持和 main.go 文件中设置的端口一样,如不一致,自行修改.
http://localhost:8080/swagger/index.html

你应该能看到 Swagger UI 界面,展示你的 API 文档。

完整的 main.go 示例

package main

import (
    "github.com/gin-gonic/gin"
    "github.com/swaggo/gin-swagger"
    "github.com/swaggo/files"
    _ "myproject/docs"
    "net/http"
)

// @title Swagger Example API
// @version 1.0
// @description This is a sample server.
// @termsOfService http://swagger.io/terms/

// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io

// @host localhost:8080
// @BasePath /

// PingExample godoc
// @Summary ping example
// @Schemes
// @Description do ping
// @Tags example
// @Accept json
// @Produce json
// @Success 200 {string} string "pong"
// @Router /ping [get]
func PingExample(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{
        "message": "pong",
    })
}

func main() {
    r := gin.Default()
    // swagger 路由
    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    r.GET("/ping", PingExample)

    r.Run()
}

注意事项:

如果修改了注释,需要重新生成文档
swag init

再次运行
go run main.go

就生效了

8. 优化代码将路由统一放在 router/routers.go 文件中

代码如下: routers.go

package router

import (
	"github.com/swaggo/gin-swagger"
	"github.com/swaggo/files"
	 _ "go-ranking/docs"
	 
	"go-ranking/controllers"
	"go-ranking/pkg/logger"
	"net/http"

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

func Router() *gin.Engine {
	r := gin.Default()
	//通过中间件调用
	r.Use(gin.LoggerWithConfig(logger.LoggerToFile()))
	r.Use(logger.Recover)

	// Swagger 访问路由
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	user := r.Group("/user")
	user.GET("/info/:id", controllers.UserController{}.GetUserInfo)
	user.POST("/list", controllers.UserController{}.GetList)

	user.PUT("/add", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "user add")
	})

	user.DELETE("/delete", func(ctx *gin.Context) {
		ctx.String(http.StatusOK, "user delete")
	})
	order := r.Group("/order")
	order.POST("/list", controllers.OrderController{}.GetList)
	return r
}

main.go

package main

import "go-ranking/router"

/// @title Swagger Example API
// @version 1.0
// @description This is a sample server.
// @termsOfService http://swagger.io/terms/

// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io

// @host localhost:9999
// @BasePath /
func main() {
	r := router.Router()

	r.Run(":9999")
}

展示 routers.go的文件中 user 路由的代码
在根目录下我创建一个Controller 来放 UserController 代码
代码如下:
package controllers

import (
	"go-ranking/models"
	"strconv"

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

type UserController struct{}

// @Summary 获取用户信息
// @Produce json
// @Param id path int true "ID"
// @Success 200 {object} models.User "成功"
// @Router /user/info/{id} [get]
// @Tags 用户接口
func (U UserController) GetUserInfo(c *gin.Context) {
	idStr := c.Param("id")
	id, _ := strconv.Atoi(idStr)
	user, _ := models.GetUserTest(id)

	ReturnSuccess(c, 1, "success", user, 1)
}

// @Summary 获取列表
// @Produce json
// @Router /user/list [POST]
// @Tags 用户接口
func (U UserController) GetList(c *gin.Context) {
	//defer func() {
	//	if err := recover(); err != nil {
	//		fmt.Println("捕获异常:", err)
	//	}
	//}()
	num1 := 1
	num2 := 0
	num3 := num1 / num2
	ReturnError(c, 4004, num3)
}

//"go-ranking/models" 这个包下的数据库操作就不展示了

Controllers/common.go 封装了返回 json 数据的结构体,代码如下:

package controllers

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

type JsonStruct struct {
	Code  int         `json:"code"`
	Msg   interface{} `json:"msg"`
	Data  interface{} `json:"data"`
	Count int64       `json:"count"`
}

type JsonErrStruct struct {
	Code int         `json:"code"`
	Msg  interface{} `json:"msg"`
}

func ReturnSuccess(c *gin.Context, code int, msg interface{}, data interface{}, count int64) {
	json := &JsonStruct{Code: code, Msg: msg, Data: data, Count: count}
	c.JSON(200, json)
}

func ReturnError(c *gin.Context, code int, msg interface{}) {
	json := &JsonErrStruct{Code: code, Msg: msg}
	c.JSON(200, json)
}

查看效果:

访问 http://localhost:9999/swagger/index.html

image.png

 将上面的注意事项的代码记得重新再执行一下,不然不会生效