Go | swagger实时更新API文档

1,490 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情

🎐 放在前面说的话

大家好,我是沥沥樱 👧🏻

本科在读,此为日常捣鼓.

如有不对,请多指教,也欢迎大家来跟我讨论鸭 👏👏👏

还有还有还有很重要的,麻烦大可爱们动动小手,给沥沥樱点颗心心♥,沥沥樱需要鼓励嗷呜~

在前后端分离的项目开发过程中,如果后端能够提供一份清晰明了的接口文档,那么就能极大地提高大家的沟通效率和开发效率。可是编写接口文档历来都是令人头痛的,而且后续接口文档的维护也十分耗费精力。有什么好办法呢?Swagger既满足我们输出文档的需要又能随代码的变更自动更新。那么我们来学一下呗~

Let’s get it!

swagger介绍

  • Swagger本质上是一种用于使用JSON表示RESTful API的接口描述语言。
  • Swagger包括自动文档,代码生成和测试用例生成。
  • Swagger单个api的注释位置,并非一定需要对应函数\方法,因为生成swagger文件时,是根据我们指定的包去扫描里面的go文件生成的

swagger注解

swagger主文件注解

注释说明示例
title必填 应用程序的名称。// @title gin-swagger
version必填 提供应用程序API的版本。// @version 1.0
description应用程序的简短描述。// @description gin+gorm 测试swagger自动生成API文档
tag.name标签的名称。// @tag.name This is the name of the tag
tag.description标签的描述。// @tag.description Cool Description
tag.docs.url标签的外部文档的URL。// @tag.docs.url example.com
tag.docs.description标签的外部文档说明。// @tag.docs.description Best example documentation
termsOfServiceAPI的服务条款。// @termsOfService swagger.io/terms/
contact.name公开的API的联系信息。// @contact.name swagger讲解文档
contact.url联系信息的URL。必须采用网址格式。// @contact.url xiaoxiami.gitbook.io/swagger/swa…
contact.email联系人/组织的电子邮件地址。 必须采用电子邮件地址的格式。// @contact.email support@swagger.io
license.name必填 用于API的许可证名称。// @license.name Apache 2.0
license.url用于API的许可证的URL。 必须采用网址格式。// @license.url www.apache.org/licenses/LI…
host运行API的主机(主机名或IP地址)。// @host localhost:8080
BasePath运行API的基本路径。// @BasePath /
acceptAPI 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。 值必须如“Mime类型”中所述。// @accept json
produceAPI可以生成的MIME类型的列表。值必须如“Mime类型”中所述。// @produce json
query.collection.format请求URI query里数组参数的默认格式:csv,multi,pipes,tsv,ssv。 如果未设置,则默认为csv。// @query.collection.format multi
schemes用空格分隔的请求的传输协议。// @schemes http https
x-name扩展的键必须以x-开头,并且只能使用json值// @x-example-key {“key”: “value”}

单个API注解

注释描述
description操作行为的详细说明。
description.markdown应用程序的简短描述。该描述将从名为endpointname.md的文件中读取。
id用于标识操作的唯一字符串。在所有API操作中必须唯一。
tags每个API操作的标签列表,以逗号分隔。
summary该操作的简短摘要
acceptAPI 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。
produceAPI可以生成的 MIME 类型的列表。
param用空格分隔的参数。param name,param type,data type,is mandatory?,comment attribute(optional)
security每个API操作的安全性。
success以空格分隔的成功响应。return code,{param type},data type,comment
failure以空格分隔的故障响应。return code,{param type},data type,comment
response与success、failure作用相同
header以空格分隔的头字段。 return code,{param type},data type,comment
router以空格分隔的路径定义。 path,[httpMethod]
x-name扩展字段必须以x-开头,并且只能使用json值。
MIME 参考手册

swagger实战(部分代码)

使用gin-swagger为我们的代码自动生成接口文档,三步骤如下:

  1. 按照swagger要求给接口代码添加声明式注释,具体参照声明式注释格式,详细注释上面有解释
  2. 使用swag工具扫描代码自动生成API接口文档数据
  3. 使用gin-swagger渲染在线接口文档页面

第一步:添加注释

主文件注释

在程序入口main函数上以注释的方式写下项目相关介绍信息。

// @title gin-swagger
// @version 1.0
// @description gin+gorm 测试swagger自动生成API文档
// @license.name Apache 2.0
// @contact.name swagger讲解文档
// @contact.url https://xiaoxiami.gitbook.io/swagger/swagger-php-wen-dang/swaggerde-jiang-jieff08-explained
// @host localhost:8080
// @BasePath /
func main() {
	dsn := "root:123123@tcp(127.0.0.1:3306)/qinli?charset=utf8mb4&parseTime=True"
	db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Silent),
	})
	if err != nil {
		panic(err.Error())
	}
	db.AutoMigrate(&Book{})
	r := gin.Default()
	r.GET("/books", Books)
	r.GET("/books/:id", Show)
	r.POST("/books", Store)
	r.DELETE("/books/:id", Delete)
	r.PATCH("/books/:id", Update)
	r.GET("/swagger/*any", gins.WrapHandler(swaggerFiles.Handler))

	r.Run(":8080")
}

单个API注释

在你代码中处理请求的接口函数(通常位于controller层)按如下方式写上注释:

// @Summary book列表
// @Description book列表
// @Tags books
// @Accept json
// @Produce json
// @Param current query int true "分页索引" default(1)
// @Param pageSize query int true "分页大小" default(10)
// @Success 200 {object} Response
// @Failure 400 {object} Response
// @Failure 500 {object} Response
// @Router /books [get]
func Books(c *gin.Context) {
	limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
	offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0"))
	var books []Book
	db.Limit(limit).Offset(offset).Find(&books)
	c.JSON(http.StatusOK, gin.H{
		"messege": "",
		"data":    books,
	})
}

// @Summary 查询book
// @Description 查询book
// @Tags books
// @Accept json
// @Produce json
// @Param id path int true "pid"
// @Success 200 {object} Response
// @Failure 400 {object} Response
// @Failure 500 {object} Response
// @Router /books/{id} [get]
func Show(c *gin.Context) {
	book := getById(c)
	c.JSON(http.StatusOK, gin.H{
		"messege": "",
		"data":    book,
	})
}

第二步:生成接口文档数据

编写完注释后,安装swag工具:

go get -u github.com/swaggo/swag/cmd/swag

(在项目根目录执行)生成接口文档数据

swag init

执行完上述命令后,如果注释格式没问题,项目根目录下会多出一个docs文件夹。

./docs
├── docs.go
├── swagger.json
└── swagger.yaml

第三步:引入gin-swagger渲染文档数据

在项目代码中注册路由的文件,按如下方式引入gin-swagger相关内容:

import (
	_ "go-swagger/docs" // 导入上一步生成的docs
	"github.com/gin-gonic/gin"
	gins "github.com/swaggo/gin-swagger"
	"github.com/swaggo/gin-swagger/swaggerFiles"
)

在项目代码中注册路由的文件,注册swagger api相关路由

    r.GET("/swagger/*any", gins.WrapHandler(swaggerFiles.Handler))

把你的项目程序运行起来,打开浏览器访问http://localhost:8080/swagger/index.html就能看到Swagger 2.0 Api文档了。


gin-swagger文档

gin-swagger同时还提供了DisablingWrapHandler函数,方便我们通过设置某些环境变量来禁用Swagger。例如:

    r.GET("/swagger/*any", gins.DisablingWrapHandler(swaggerFiles.Handler, "NAME_OF_ENV_VARIABLE"))

此时如果将环境变量NAME_OF_ENV_VARIABLE设置为任意值,则/swagger/*any将返回404响应,就像未指定路由时一样。

🎉 放在后面说的话

通过以上的一顿操作,大家应该都能学会了hhh~o( ̄▽ ̄)ブ