咱们都知道在 API 开发中,文档是必不可少的一环。

swaggo/swag 是一个用于 Go 语言的自动化生成 API 文档的工具,它可以将代码注释转换为 Swagger 文档,方便开发者和用户理解 API 的使用方法。

本文将详细介绍 swaggo/swag 的使用方式以及它的特性。

1. 安装 Swaggo/Swag

先在你的 Go 项目中安装 swag 命令行工具和 gin-swagger 依赖:

# 安装 swag 命令行工具
go install github.com/swaggo/swag/cmd/swag@latest

# 安装 gin-swagger 和 swagger 文件的依赖
go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files

2. Swag 的基本特性

swaggo/swag 可以解析代码中的注释,并将其生成 Swagger 格式的文档文件。生成的文档可以通过网页进行查看和测试。主要特性如下:

  1. 自动生成 API 文档:通过扫描代码中的注释,将注释内容转换为 OpenAPI 规范的 Swagger 文档。
  2. 灵活的注释方式:支持丰富的注释语法,开发者可以在注释中描述接口的详细信息,包括请求参数、响应结构等。
  3. 内嵌 Swagger UI:生成的 API 文档可以通过网页查看,并使用 Swagger UI 直接进行 API 测试。
  4. 支持多种 Web 框架:支持常见的 Go Web 框架,如 Gin、Echo、Fiber 等。
  5. 定制化:可以通过注释自定义文档的内容,包括参数、响应、错误代码等。

3. Swag 的基本使用

3.1 项目结构

为了更好地演示 swaggo/swag 的使用,假设我们的项目目录结构如下:

myapp/
├── docs/
├── main.go

其中,docs/ 文件夹是生成的 Swagger 文档将要存放的目录。

3.2 在代码中添加注释

在你的 Go 代码中,使用 swag 的注释格式为 API 接口添加注释。以下是一个使用 Gin 框架的示例,main.go 文件中的代码如下:

package main

import (
 "github.com/gin-gonic/gin"
 _ "myapp/docs" // 引入 docs 包,以便 swag 自动生成文档
 swaggerFiles "github.com/swaggo/files"
 ginSwagger "github.com/swaggo/gin-swagger"
 "net/http"
)

// @title Swagger Example API
// @version 1.0
// @description 这是一个简单的 API 文档示例
// @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 /api/v1

func main() {
 r := gin.Default()

 // 设置 Swagger 文档的路由
 r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

 // 注册 API 路由
 api := r.Group("/api/v1")
 {
  api.GET("/hello", helloWorld)
 }

 // 启动服务
 r.Run(":8080")
}

// @Summary 说你好
// @Description 输出一个问候信息
// @Tags hello
// @Accept json
// @Produce json
// @Success 200 {string} string "success"
// @Router /hello [get]
func helloWorld(c *gin.Context) {
 c.JSON(http.StatusOK, gin.H{
  "message": "Hello, world!",
 })
}
3.3 生成 Swagger 文档

运行以下命令来生成 Swagger 文档:

swag init

执行上述命令后,swag 会扫描你的代码并生成文档文件,默认会在 docs/ 文件夹下生成 docs.goswagger.json

3.4 运行应用并查看 Swagger 文档

启动应用后,在浏览器中访问 http://localhost:8080/swagger/index.html,即可查看自动生成的 Swagger 文档。

4. Swag 注释详解

swaggo/swag 的注释语法非常灵活,可以在注释中详细描述 API 接口的功能。常用的注释关键字如下:

4.1 基本注释
  • @title:文档的标题。
  • @version:API 的版本。
  • @description:对 API 的描述。
  • @termsOfService:服务条款的 URL。
  • @contact.name、**@contact.url@contact.email**:联系信息。
  • @host:API 的主机地址。
  • @BasePath:API 的基础路径。
4.2 路由注释
  • @Router:指定接口的 URL 路径和 HTTP 方法。
  • @Summary:接口的简要描述。
  • @Description:接口的详细描述。
  • @Tags:接口的分类标签。
  • @Accept:指定请求的 MIME 类型,例如 json
  • @Produce:指定响应的 MIME 类型,例如 json
  • @Param:描述接口的参数,例如查询参数、路径参数、请求体等。
  • @Success:描述接口的成功响应。
  • @Failure:描述接口的失败响应。
  • @Header:描述响应头。
  • @Security:描述接口的安全性,例如 BasicAuth、APIKey、BearerToken 等。

5. 更高级的特性

5.1 参数注释

@Param 用于描述接口的请求参数,支持路径参数、查询参数、请求体等多种类型。

// @Param id path int true "用户ID"
// @Param name query string false "用户名"
// @Param body body models.User true "用户信息"
  • path:路径参数。
  • query:查询参数。
  • body:请求体。
5.2 响应注释
  • @Success@Failure 用于描述接口的成功和失败响应。
// @Success 200 {object} models.User "成功时返回的用户信息"
// @Failure 400 {string} string "请求参数错误"
// @Failure 404 {string} string "找不到指定的资源"
5.3 安全性

@Security 用于描述 API 的安全机制。

// @Security ApiKeyAuth

6. 运行时动态设置 Swagger 信息

swaggo/swag 生成的 Swagger 文档是静态的,但你可以在运行时通过 Go 代码来动态更新文档内容。

例如,在特定条件下更改 Swagger 信息:

import "github.com/swaggo/swag"

swag.SwaggerInfo.Title = "My Dynamic API"
swag.SwaggerInfo.Host = "api.example.com"
swag.SwaggerInfo.Version = "2.0"
swag.SwaggerInfo.BasePath = "/v2"

7. 集成到现有 CI/CD 管道

swaggo/swag 可以轻松集成到 CI/CD 管道中,自动生成和验证 Swagger 文档。

例如,在 CI 环境中运行 swag init 以确保每次构建的 API 文档都是最新的。

7.1 在 CI 中自动生成文档

可以在 CI/CD 脚本中添加以下命令:

swag init
go test ./...
go build -o myapp

8. 支持多种 Web 框架

swaggo/swag 支持多种常见的 Web 框架,包括:

  • Gin: 通过 gin-swagger 集成 Swagger UI。
  • Echo: 使用 echo-swagger 集成 Swagger UI。
  • Fiber: 使用 fiber-swagger 集成 Swagger UI。

使用方式类似,只需要替换对应框架的包和路由配置。

9. 支持复杂数据结构的注解

swaggo/swag 支持对复杂数据结构进行注解,可以通过 Go 语言的结构体嵌套和注释来描述复杂的请求体和响应体。

这个特性非常适合生成包含嵌套 JSON 的 API 文档。

9.1 嵌套结构体示例
type Address struct {
 Street  string `json:"street"`
 City    string `json:"city"`
 ZipCode string `json:"zip_code"`
}

type User struct {
 ID      int      `json:"id"`
 Name    string   `json:"name"`
 Email   string   `json:"email"`
 Address Address  `json:"address"`
}

// @Summary 获取用户信息
// @Description 根据用户ID获取用户详细信息
// @Tags user
// @Produce json
// @Param id path int true "用户ID"
// @Success 200 {object} User "返回用户信息"
// @Failure 404 {object} string "用户未找到"
// @Router /user/{id} [get]
func getUser(c *gin.Context) {
 // 实现获取用户的逻辑
}
  • 通过在注释中使用 {object} Userswaggo/swag 会自动生成该结构体及其嵌套结构体的描述。

10. 自定义注解

swaggo/swag 允许自定义注解来描述 API 的请求和响应,以支持多种不同的业务需求。

可以通过 @Param@Success@Failure 等注解来自定义接口的输入输出。

10.1 自定义注解示例
// @Summary 创建新用户
// @Description 使用 JSON 格式的请求体创建一个新用户
// @Tags user
// @Accept json
// @Produce json
// @Param user body User true "用户信息"
// @Success 201 {object} User "创建成功返回的用户信息"
// @Failure 400 {object} string "请求参数错误"
// @Failure 500 {object} string "服务器内部错误"
// @Router /user [post]
func createUser(c *gin.Context) {
 // 实现创建用户的逻辑
}
  • 通过自定义注解,可以明确指定请求体的格式和结构,以及响应的类型和状态码。

11. 分组注解

swaggo/swag 提供了 @Tags 注解来对 API 进行分组。

使用分组功能可以让 API 文档更加清晰,便于查找和分类。

11.1 分组接口示例
// @Summary 登录接口
// @Tags auth
// @Accept json
// @Produce json
// @Param credentials body LoginRequest true "登录凭据"
// @Success 200 {string} string "登录成功"
// @Failure 401 {string} string "认证失败"
// @Router /login [post]
func login(c *gin.Context) {
 // 实现登录逻辑
}

在 Swagger UI 中,API 会按标签进行分组,例如将所有用户相关的接口放在 "user" 标签下,将所有身份验证相关的接口放在 "auth" 标签下。

12. 支持多文件注解

在一个大型的项目中,API 可能会被拆分到多个文件中。swaggo/swag 支持多文件注解,只要在每个文件中包含注释,swag init 命令就会扫描整个项目中的注释并生成文档。

12.1 项目结构
myapp/
├── main.go
├── handlers/
│   ├── user.go
│   └── auth.go
└── docs/

user.goauth.go 中分别添加注解,swag init 命令会自动扫描并合并这些文件中的注解信息。

13. 支持定制 Swagger 文档

swaggo/swag 允许你自定义生成的 Swagger 文档,包括 swagger.jsonswagger.yaml

你可以通过注解和配置文件来更改文档内容,例如指定 API 的版本、标题、描述、许可证等。

13.1 自定义文档信息

通过在 main.go 文件中使用注解设置全局文档信息:

// @title My API
// @version 1.0
// @description 这是我的 API 文档。
// @termsOfService http://example.com/terms/

// @contact.name API Support
// @contact.url http://www.example.com/support
// @contact.email support@example.com

// @license.name MIT
// @license.url https://opensource.org/licenses/MIT

// @host localhost:8080
// @BasePath /api/v1
  • 这些注解可以定制文档的元信息,如标题、描述、联系信息和许可证信息。

14. 支持 API 安全性设置

swaggo/swag 支持为 API 设置安全性,例如 OAuth2、API Key、Basic Auth 等。

可以通过注解指定 API 的安全机制。

14.1 设置 Basic Auth
// @Security BasicAuth
// @Summary 受保护的接口
// @Tags protected
// @Success 200 {string} string "成功"
// @Router /protected [get]
func protectedEndpoint(c *gin.Context) {
 // 实现逻辑
}

15. 请求和响应示例

在文档中添加请求和响应的示例数据,使接口更加直观。可以通过注解提供示例值。

15.1 添加示例数据
// @Param user body User true "用户信息" default({"name": "John Doe", "email": "john@example.com"})
// @Success 200 {object} User "创建成功返回的用户信息" example({"id": 1, "name": "John Doe", "email": "john@example.com"})

16. 注解支持多种类型

  • intstringbool 等基本类型。
  • **object**:用于描述嵌套结构体。
  • **array**:用于描述数组类型,例如 []string
  • **file**:用于文件上传接口。
// @Param file formData file true "文件上传"

17. 支持响应头信息

通过注解添加自定义的响应头信息,增强接口描述。

// @Header 200 {string} X-Token "服务器返回的 Token"

18. 接口描述的丰富性

swaggo/swag 的注解非常灵活,可以为接口添加详细的描述,包括请求参数的类型、必填性、默认值、取值范围等,帮助开发者更好地理解和使用 API。

19. 多语言支持

虽然 swaggo/swag 本身没有直接提供多语言支持,但生成的文档可以在 Swagger-UI 中显示不同的语言。

Swagger-UI 可以根据浏览器设置自动适配不同的语言界面,这为国际化项目提供了便利。

20. 使用自定义模板

swaggo/swag 支持使用自定义模板来生成 Swagger 文档。

通过自定义模板,你可以根据自己的需求,改变 Swagger 文档的结构和样式。

自定义模板为那些希望定制化 API 文档风格的团队提供了灵活性。

20.1 自定义模板示例

创建一个自定义模板文件,例如 template/custom.tmpl

{
  "swagger": "2.0",
  "info": {
    "title": "{{.Title}}",
    "description": "{{.Description}}",
    "version": "{{.Version}}"
  },
  "paths": {
    {{range .Paths}}
    "{{.Path}}": {
      "get": {
        "summary": "{{.Summary}}",
        "operationId": "{{.OperationID}}",
        "parameters": [{{range .Parameters}}{{.Name}}: {{.Type}}{{end}}]
      }
    }
    {{end}}
  }
}

通过 swag 工具使用自定义模板:

swag init --template template/custom.tmpl

21. 中间件支持

swaggo/swag 生成的文档可以与各种中间件集成,例如身份验证、CORS(跨域资源共享)、速率限制等。这使得你可以通过中间件控制对 Swagger 文档的访问权限。

21.1 在 Gin 中使用中间件

Gin 中使用身份验证中间件保护 Swagger 文档:

authMiddleware := func(c *gin.Context) {
 token := c.GetHeader("Authorization")
 if token != "expected-token" {
  c.AbortWithStatus(http.StatusUnauthorized)
  return
 }
 c.Next()
}

r := gin.Default()
r.GET("/swagger/*any", authMiddleware, ginSwagger.WrapHandler(swaggerFiles.Handler))

22. 支持全局参数

有时你的 API 需要在每个请求中包含相同的全局参数,例如 Authorization 头部或者语言参数。swaggo/swag 支持在生成的文档中添加全局参数定义。

22.1 定义全局参数

通过注释为文档添加全局参数:

// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
  • 通过 @securityDefinitions 注解定义一个全局的 API 密钥认证方式,所有需要此认证的路由都可以共享这个定义。

23. 使用 YAML 格式文档

默认情况下,swaggo/swag 会生成 JSON 格式的 Swagger 文档。

但是,如果你更喜欢 YAML 格式,也可以生成 YAML 格式的文档。你只需要修改代码来支持从 swagger.yaml 读取数据。

23.1 生成 YAML 文档

通过 swag 工具可以生成 YAML 格式的文档:

swag init --output docs --format yaml

生成的 YAML 文件通常会放在 docs/swagger.yaml 中,可以在应用启动时读取这个文件,提供 API 文档服务。

24. 自定义请求/响应示例和枚举值

通过注解,你可以在文档中详细定义请求和响应示例数据,并且为参数指定枚举值。

24.1 定义枚举值
// @Param status query string true "订单状态" Enums(pending, paid, shipped)
  • 使用 Enums 关键字指定参数的可选值。
24.2 添加请求示例
// @Param user body User true "用户信息" example({"name": "John Doe", "email": "john@example.com"})
  • 使用 example 关键字为请求体添加示例数据。

这样可以在每次提交代码后,自动更新文档并运行测试。

25. 支持多版本 API 文档

对于一个大型应用来说,支持多版本的 API 是非常重要的。

swaggo/swag 可以通过不同的 @BasePath 注解来区分不同版本的 API。

25.1 定义多版本 API
// @BasePath /api/v1
// @BasePath /api/v2

在项目中可以定义多个版本的 API,每个版本对应不同的 BasePath,以在 Swagger 文档中清晰地展示不同版本的接口。

26. 可扩展性:支持自定义 Swagger 插件

如果你对 swaggo/swag 的默认行为不满意,可以开发自定义插件来扩展 Swagger 文档的生成过程。这使得 swaggo/swag 成为一个高度可扩展的文档生成工具。

27. 生成离线文档

swaggo/swag 生成的 Swagger 文档(swagger.jsonswagger.yaml)可以通过 swagger-ui 工具生成离线文档,方便你在无网络环境下使用。

27.1 使用 Swagger-UI 生成离线文档

你可以使用 Swagger-UI 官方提供的工具,将生成的 swagger.jsonswagger.yaml 嵌入到静态 HTML 文件中,形成离线可访问的文档。

swagger-ui-dist/swagger-ui-bundle.js swagger.json > index.html

最后

这绝对算得上是保姆级的使用指南了吧!

通过 swaggo/swag,你可以快速为 Go 项目生成专业的、丰富的 API 文档,极大地提高开发效率和文档质量。

赶紧使用起来吧!

在我封装的框架中,生成的 API 文档使用的正是 swaggo/swag

最后,谢谢你看到了这里👏 想要第一时间接收到推送,可以点个关注。