79·常用库进阶

API 文档:Swagger

swaggeropenapiswagdoc

第79课 - API文档:Swagger

学习目标

完成本课后,你将能够:

  1. 理解 Swagger (OpenAPI) 在 RESTful API 开发中的作用与优势
  2. 掌握使用 swag 工具为 Go Web API 自动生成交互式文档
  3. 学会编写符合规范的注释,以便工具正确解析
  4. 能够在 Gin 或其他框架中集成并访问 Swagger UI
  5. 了解如何结合上一课的验证库,为 API 文档添加参数校验说明

核心概念

什么是 Swagger?

想象一下,你开发了一个 Web API,需要告诉前端开发者“有哪些接口、怎么调用、参数是什么格式”。传统做法是写一份 Word 文档或维护一个 Wiki,但很容易与代码不同步。

Swagger (现称为 OpenAPI) 是一个规范,用于描述 RESTful API 的接口、参数、数据模型等信息。基于这个规范,有大量工具可以:

  • 自动生成 接口文档
  • 提供交互式 的测试界面 (Swagger UI)
  • 生成 客户端代码(如前端、移动端 SDK)

简单来说,你只需在代码中按特定格式写注释,swag 工具就能将注释转换成标准的 OpenAPI (JSON/YAML) 文档,再通过 Swagger UI 展示出来。

为什么使用 swag?

在 Go 生态中,swag 是最流行的工具,它能解析 Go 源代码中的注释,生成 Swagger 2.0 文档。主要流程是:

  1. 在控制器函数、模型结构体上添加特定格式的注释。
  2. 运行 swag init 命令扫描代码。
  3. 生成 docs 目录和 JSON 文件。
  4. 在 Web 服务中引入并注册 Swagger 路由。

这样,你的 API 文档就和代码永远同步了。

代码示例

我们以一个简单的 Gin 框架项目为例,创建一个“用户管理”API 并生成 Swagger 文档。

1. 项目初始化与安装

# 初始化模块
go mod init swagger-demo

# 安装核心依赖
go get -u github.com/gin-gonic/gin
go get -u github.com/swaggo/swag/cmd/swag  # 安装 CLI 工具
go get -u github.com/swaggo/gin-swagger   # Gin 的中间件
go get -u github.com/swaggo/files          # 静态文件

2. 创建主文件 main.go

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
	_ "swagger-demo/docs" // 重要:导入生成的文档包

	ginSwagger "github.com/swaggo/gin-swagger"
	"github.com/swaggo/gin-swagger/swaggerFiles"
)

// User 用户模型
// @Description 用户信息结构体
type User struct {
	ID   int    `json:"id" example:"1"`
	Name string `json:"name" example:"张三"`
	Age  int    `json:"age" example:"25"`
}

// GetUser 根据ID获取用户
// @Summary 获取单个用户
// @Description 根据用户ID获取用户详细信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param id path int true "用户ID" example(1)
// @Success 200 {object} User "成功"
// @Failure 404 {object} map[string]string "用户不存在"
// @Router /users/{id} [get]
func GetUser(c *gin.Context) {
	id := c.Param("id")
	// 模拟数据库查询
	if id == "1" {
		c.JSON(http.StatusOK, User{ID: 1, Name: "张三", Age: 25})
	} else {
		c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
	}
}

// CreateUser 创建新用户
// @Summary 创建用户
// @Description 创建一个新用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param user body User true "用户信息 (注意:此处ID由后端分配,可忽略)"
// @Success 201 {object} User "创建成功"
// @Failure 400 {object} map[string]string "参数错误"
// @Router /users [post]
func CreateUser(c *gin.Context) {
	var newUser User
	if err := c.ShouldBindJSON(&newUser); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	// 模拟分配ID并存储
	newUser.ID = 2
	c.JSON(http.StatusCreated, newUser)
}

// @title 用户管理API
// @version 1.0
// @description 这是使用Swagger生成的API文档示例。
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.example.com/support
// @contact.email [email protected]
// @host localhost:8080
// @BasePath /
func main() {
	r := gin.Default()

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

	r.GET("/users/:id", GetUser)
	r.POST("/users", CreateUser)

	r.Run(":8080")
}

3. 生成文档并运行

在项目根目录执行:

# 生成文档(-d . 表示扫描当前目录)
swag init -d .

这会创建 docs 目录。然后运行:

go run main.go

访问 http://localhost:8080/swagger/index.html,你将看到一个美观的交互式文档页面,可以直接测试 API 接口。

实践练习

练习1:基础注释练习

为以下函数添加完整的 Swagger 注释,使其能够正确生成文档。该函数用于根据年龄范围查询用户列表。

// GetUsersByAge 根据年龄范围查询用户
func GetUsersByAge(c *gin.Context) {
    minAge := c.Query("min_age")
    maxAge := c.Query("max_age")
    // ... 业务逻辑
    c.JSON(200, []User{})
}

要求

  • 标签为 用户管理
  • 接受 JSON 并返回 JSON
  • 定义两个查询参数 min_agemax_age,类型为整数,必填
  • 成功时返回用户数组

练习2:模型嵌套练习

定义以下两个结构体,并为 Order 结构体及其字段编写注释,使其在文档中正确显示嵌套的 User 信息。

type Order struct {
    ID     int    `json:"id"`
    Item   string `json:"item"`
    Amount int    `json:"amount"`
    // 用户信息应该嵌套显示
}

要求:使用 swaggo/swag 支持的模型引用语法,让文档中 Order 包含完整的 User 字段。

练习3:分组与验证练习

使用 Gin 的路由组,将所有用户相关接口放在 /api/v1/users 路径下。并结合 go-playground/validator 为创建用户的接口添加字段验证(如 Name 不能为空,Age 必须大于0),然后在 Swagger 注释中说明验证规则。

常见错误

  1. 忘记重新生成文档:修改注释后,必须重新运行 swag init。否则文档不会更新。
  2. 注释格式错误:严格遵循 // @ 格式,不要有多余空格或换行。例如 @Param@Success 的格式非常严格。
  3. 缺少必要的注释:在 main 函数上方的包级别注释(@title 等)是必须的,否则 swag init 会报错。
  4. 忘记导入 docs 包:在 main.go 中必须导入 _ "your-module/docs",否则服务启动时会找不到文档数据。
  5. 模型未导出或注释不完整:结构体字段首字母必须大写(导出),并且需要使用 example 标签提供示例值,否则文档中该字段显示为 null 或空。

小结

  • Swagger/OpenAPI 是描述和文档化 API 的行业标准,能保持文档与代码同步。
  • swag 工具是 Go 生态中生成 Swagger 文档的首选,它通过解析特定格式的注释来工作。
  • 工作流程:编写带注释的代码 → 运行 swag init → 引入并注册 swagger 路由 → 访问 /swagger/index.html
  • 关键注释@Summary, @Param, @Success, @Router 是最常用的几个,需要熟练掌握。
  • 与验证结合:可以在注释的 @Description 中说明验证规则,或使用更高级的扩展来实现。

通过本课,你已掌握了自动化 API 文档生成的核心技能。这将极大地提升团队协作效率和 API 的可维护性。下一课我们将学习功能强大的测试框架 Testify,让测试代码更简洁、更强大。

练习编辑器

go
Loading...

继续学习

完成本课后,建议继续学习下一课「测试框架:Testify」 以巩固所学知识。