字数 2895,阅读大约需 15 分钟
分享我在Gin里使用Swag生成API文档,提效开发
摘要
本文旨在介绍如何在Gin里生成API文档
,哈哈(≧ω≦);分享我在使用Gin的时候,将代码转为API,然后演示在Swagger浏览器页面或者是apifox里调用代码里的业务API;
定义
Swagger(现在叫OpenAPI)
1. 是一套规范标准,定义了如何描述RESTful API
2. 提供了可视化的API文档界面,让开发者可以直接在网页上测试API
3. 输出格式:swagger.json 或 swagger.yaml 文件
4. 语言无关,几乎所有主流编程语言都有支持工具
Swag
1. 专门为Go语言开发的工具
2. 通过解析Go代码中的特殊注释自动生成Swagger文档
3. 主要命令:swag init 生成docs文件夹和相关文档文件
4. 代码中添加类似 // @Summary // @Description 这样的注释
Swagger
1. gin框架的中间件
2. swag生成的文档集成到Gin应用中
3. 提供了 /swagger/index.html 这样的路由来访问文档页面
4. 让用户可以直接在浏览器中查看和测试API
开发演示
mian.go
对应的字段含义,可在官方文档或者AI查询到使用说明,建议在开发的时候多查查,通过实践锻炼理解文档;
package main
import (
swaggerFiles "github.com/swaggo/files" // swagger embed files
ginSwagger "github.com/swaggo/gin-swagger" // gin-swagger middleware
)
// 程序入口
// @title Swagger Example API
// @version 1.0
// @description This is a sample server celler server.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email [email protected]
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8992
// @BasePath /api/v1/gin
// @securityDefinitions.basic BasicAuth
// @externalDocs.description OpenAPI
// @externalDocs.url https://swagger.io/resources/open-api/
api代码里
// 创建服务工单
// ShowAccount godoc
// @Summary create a workorder
// @Description get string by ID
// @Tags WorkOrder
// @Accept json
// @Produce json
// @Param data body schema.WorkOrderCreate true "工单"
// @Router /workorder/ [post]
func CreateWorkOrder(c *gin.Context) {
}
swagger
官方文档
swag/README_zh-CN.md at master · swaggo/swag[1]
快速开始
中文文档[2]
1. 将注释添加到API源代码中,请参阅声明性注释格式。
2. 使用如下命令下载swag:
go install github.com/swaggo/swag/cmd/swag@latest
从源码开始构建的话,需要有Go环境(1.19及以上版本)。
或者从github的release页面下载预编译好的二进制文件。
3. 在包含
main.go
文件的项目根目录运行swag init
。这将会解析注释并生成需要的文件(docs
文件夹和docs/docs.go
)。
swag init
确保导入了生成的 docs/docs.go
文件,这样特定的配置文件才会被初始化。如果通用API注释没有写在 main.go
中,可以使用 -g
标识符来告知swag。
swag init -g http/api.go
4. (可选) 使用
fmt
格式化 SWAG 注释。(请先升级到最新版本)
swag fmt
swag cli
[3]
swag init -h
NAME:
swag init - Create docs.go
USAGE:
swag init [command options] [arguments...]
OPTIONS:
--generalInfo value, -g value API通用信息所在的go源文件路径,如果是相对路径则基于API解析目录 (默认: "main.go")
--dir value, -d value API解析目录 (默认: "./")
--exclude value 解析扫描时排除的目录,多个目录可用逗号分隔(默认:空)
--propertyStrategy value, -p value 结构体字段命名规则,三种:snakecase,camelcase,pascalcase (默认: "camelcase")
--output value, -o value 文件(swagger.json, swagger.yaml and doc.go)输出目录 (默认: "./docs")
--parseVendor 是否解析vendor目录里的go源文件,默认不
--parseDependency 是否解析依赖目录中的go源文件,默认不
--parseDependencyLevel, --pdl 对'--parseDependency'参数进行增强, 是否解析依赖目录中的go源文件, 0 不解析, 1 只解析对象模型, 2 只解析API, 3 对象模型和API都解析 (default: 0)
--markdownFiles value, --md value 指定API的描述信息所使用的markdown文件所在的目录
--generatedTime 是否输出时间到输出文件docs.go的顶部,默认是
--codeExampleFiles value, --cef value 解析包含用于 x-codeSamples 扩展的代码示例文件的文件夹,默认禁用
--parseInternal 解析 internal 包中的go文件,默认禁用
--parseDepth value 依赖解析深度 (默认: 100)
--instanceName value 设置文档实例名 (默认: "swagger")
swag fmt -h
NAME:
swag fmt - format swag comments
USAGE:
swag fmt [command options] [arguments...]
OPTIONS:
--dir value, -d value API解析目录 (默认: "./")
--exclude value 解析扫描时排除的目录,多个目录可用逗号分隔(默认:空)
--generalInfo value, -g value API通用信息所在的go源文件路径,如果是相对路径则基于API解析目录 (默认: "main.go")
--help, -h show help (default: false)
如何与Gin集成
[4]
点击此处[5]查看示例源代码。
1. 使用
swag init
生成Swagger2.0文档后,导入如下代码包:
import "github.com/swaggo/gin-swagger" // gin-swagger middleware
import "github.com/swaggo/files" // swagger embed files
2. 在
main.go
源代码中添加通用的API注释:
// @title Swagger Example API
// @version 1.0
// @description This is a sample server celler server.
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email [email protected]
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// @BasePath /api/v1
// @securityDefinitions.basic BasicAuth
// @externalDocs.description OpenAPI
// @externalDocs.url https://swagger.io/resources/open-api/
func main() {
r := gin.Default()
c := controller.NewController()
v1 := r.Group("/api/v1")
{
accounts := v1.Group("/accounts")
{
accounts.GET(":id", c.ShowAccount)
accounts.GET("", c.ListAccounts)
accounts.POST("", c.AddAccount)
accounts.DELETE(":id", c.DeleteAccount)
accounts.PATCH(":id", c.UpdateAccount)
accounts.POST(":id/images", c.UploadAccountImage)
}
//...
}
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.Run(":8080")
}
//...
此外,可以动态设置一些通用的API信息。生成的代码包 docs
导出 SwaggerInfo
变量,使用该变量可以通过编码的方式设置标题、描述、版本、主机和基础路径。使用Gin的示例:
package main
import (
"github.com/gin-gonic/gin"
"github.com/swaggo/files"
"github.com/swaggo/gin-swagger"
"./docs" // docs is generated by Swag CLI, you have to import it.
)
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email [email protected]
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
func main() {
// programatically set swagger info
docs.SwaggerInfo.Title = "Swagger Example API"
docs.SwaggerInfo.Description = "This is a sample server Petstore server."
docs.SwaggerInfo.Version = "1.0"
docs.SwaggerInfo.Host = "petstore.swagger.io"
docs.SwaggerInfo.BasePath = "/v2"
docs.SwaggerInfo.Schemes = []string{"http", "https"}
r := gin.New()
// use ginSwagger middleware to serve the API docs
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.Run()
}
3. 在
controller
代码中添加API操作注释:
package controller
import (
"fmt"
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/swaggo/swag/example/celler/httputil"
"github.com/swaggo/swag/example/celler/model"
)
// ShowAccount godoc
// @Summary Show an account
// @Description get string by ID
// @Tags accounts
// @Accept json
// @Produce json
// @Param id path int true "Account ID"
// @Success 200 {object} model.Account
// @Failure 400 {object} httputil.HTTPError
// @Failure 404 {object} httputil.HTTPError
// @Failure 500 {object} httputil.HTTPError
// @Router /accounts/{id} [get]
func (c *Controller) ShowAccount(ctx *gin.Context) {
id := ctx.Param("id")
aid, err := strconv.Atoi(id)
if err != nil {
httputil.NewError(ctx, http.StatusBadRequest, err)
return
}
account, err := model.AccountOne(aid)
if err != nil {
httputil.NewError(ctx, http.StatusNotFound, err)
return
}
ctx.JSON(http.StatusOK, account)
}
// ListAccounts godoc
// @Summary List accounts
// @Description get accounts
// @Tags accounts
// @Accept json
// @Produce json
// @Param q query string false "name search by q" Format(email)
// @Success 200 {array} model.Account
// @Failure 400 {object} httputil.HTTPError
// @Failure 404 {object} httputil.HTTPError
// @Failure 500 {object} httputil.HTTPError
// @Router /accounts [get]
func (c *Controller) ListAccounts(ctx *gin.Context) {
q := ctx.Request.URL.Query().Get("q")
accounts, err := model.AccountsAll(q)
if err != nil {
httputil.NewError(ctx, http.StatusNotFound, err)
return
}
ctx.JSON(http.StatusOK, accounts)
}
//...
swag init
http://localhost:8992/swagger/index.html#/
详细声明注释格式
swag/README_zh-CN.md at master · swaggo/swag[6]
mian.go
api.go
mime
参数类型
[17]
• query
• path
• header
• body
• formData
数据类型
[18]
• string (string)
• integer (int, uint, uint32, uint64)
• number (float32)
• boolean (bool)
• user defined struct
More: 见官方文档:swag/README_zh-CN.md at master · swaggo/swag[19]
引用链接
[1]
swag/README_zh-CN.md at master · swaggo/swag: https://github.com/swaggo/swag/blob/master/README_zh-CN.md[2]
中文文档: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B[3]
: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#swag-cli[4]
: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#%E5%A6%82%E4%BD%95%E4%B8%8Egin%E9%9B%86%E6%88%90[5]
点击此处: https://github.com/swaggo/swag/tree/master/example/celler[6]
swag/README_zh-CN.md at master · swaggo/swag: https://github.com/swaggo/swag/blob/master/README_zh-CN.md[7]
https://example.com: https://example.com/[8]
[email protected]: mailto:[email protected][9]
Mime类型: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#mime%E7%B1%BB%E5%9E%8B[10]
Mime类型: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#mime%E7%B1%BB%E5%9E%8B[11]
Mime类型: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#mime%E7%B1%BB%E5%9E%8B[12]
Mime类型: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#mime%E7%B1%BB%E5%9E%8B[13]
安全性: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#%E5%AE%89%E5%85%A8%E6%80%A7[14]
Mime类型: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#mime%E7%B1%BB%E5%9E%8B[15]
Mime类型: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#mime%E7%B1%BB%E5%9E%8B[16]
安全性: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#%E5%AE%89%E5%85%A8%E6%80%A7[17]
: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#%E5%8F%82%E6%95%B0%E7%B1%BB%E5%9E%8B[18]
: https://github.com/swaggo/swag/blob/master/README_zh-CN.md#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B[19]
swag/README_zh-CN.md at master · swaggo/swag: https://github.com/swaggo/swag/blob/master/README_zh-CN.md
评论区