Go 项目自动生成 Swagger API 文档教程

## Swagger 文档基本介绍

Swagger 2.0 和 OpenAPI 3.0 都是用于描述 **[RESTful API](https://apifox.com/apiskills/rest-api/)** 的规范。它们的主要目的是使不同的开发者和团队能够轻松地了解和使用 API,同时提高 API 的可维护性和互操作性。

Swagger 2.0 是早期版本的规范,它定义了一组基于 JSON 或 YAML 的规则,以描述 API 的各种方面,如端点、操作、参数、响应等。Swagger 2.0 可以通过 Swagger UI 在浏览器中直接查看 API 的文档和测试 API。它已成为一个流行的 API 规范,并被许多公司和开发者广泛采用。

OpenAPI 3.0 是 Swagger 2.0 的后续版本。它是一种更加灵活和强大的 API 规范,具有更丰富的功能和更好的可扩展性。OpenAPI 3.0 采用了 YAML 语法,并增加了许多新的功能,如结构化的响应定义、请求体定义、更好的错误处理等。与 Swagger 2.0 不同,OpenAPI 3.0 可以定义 SOAP 和 RPC API,而不仅仅是 RESTful API。OpenAPI 3.0 也提供了一个基于 JSON 的默认格式,可以使用许多不同的工具生成 API 文档和客户端代码。

## Go 生态中 Swagger 开源项目介绍

### go-swagger

go-swagger 是一个用于构建、文档化和测试 Go RESTful API 的工具。它支持 Swagger 2.0 和 OpenAPI 3.0 规范,并提供了生成客户端和服务器端代码的功能。使用 go-swagger 可以简化 API 的开发和维护,并提高 API 的可读性和可测试性。

### swag

swag 是一个用于自动生成 **[Swagger](https://apifox.com/apiskills/what-is-swagger/)** 文档的 Go 注释工具。它可以解析 Go 源代码中的 Swagger 注释,并将它们转换为 Swagger 文档。使用swag可以快速生成Swagger文档,提高API的可读性和可测试性。

### kin-openapi

kin-openapi 是一个用于验证和解析 OpenAPI 3.0 规范的 Go 库。它提供了一组工具,可以轻松地加载、验证和操作 OpenAPI 文档。使用 kin-openapi 可以确保你的 API 符合 **[OpenAPI 规范](https://openapi.apifox.cn/)**,并提高 API 的可靠性和可测试性。

### oapi-codegen

oapi-codegen 是一个用于生成 Go 客户端和服务器端代码的 OpenAPI 3.0 代码生成器。它基于 OpenAPI 规范,可以将 OpenAPI 文档转换为可用的 Go 代码。使用 oapi-codegen 可以加速 API 的开发过程,同时提高代码的可靠性和可测试性。

你需要 OpenAPI V3 还是 Swagger 2.0 ? 截止到目前, 我还没有找到一个合适的工具能直接在 Go 项目中生成 OpenAPI 3.0 文档。所以接下来会介绍快速生成 Swagger 2.0 的步骤。

## 快速生成 Swagger 2.0 的步骤

### **接入流程**

接入流程主要分为以下几个步骤:

1. main 文件中添加注释-配置 Server,服务信息
2. controller 中添加注释-配置接口,接口信息
3. swag init 生成 docs 目录
4. 配置 handler 访问

### 示例项目

大家可以参考[**这个项目**](https://github.com/lixd/i-go/tree/master/gin/swagger)

### 安装swag

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

支持解析并输出 docs/docs.go

### 配置服务信息

main.go 中引入以下两个包:

```arduino
import "github.com/swaggo/gin-swagger" // gin-swagger middleware
import "github.com/swaggo/files" // swagger embed files
```

安装必要拓展

```arduino
go get -u -v github.com/swaggo/gin-swagger
go get -u -v github.com/swaggo/files
go get -u -v github.com/alecthomas/template
```

### 添加 server 描述

```go
// 添加注释以描述 server 信息
// @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 support@swagger.io
// @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
func main() {
r := gin.Default() c := controller.NewController() v1 := r.Group("/api/v1") { accounts := v1.Group("/accounts") { accounts.GET(":id", c.ShowAccount) } //...
}
r.Run(":8080")}//...
```

最新的定义可以查看官网文档, 以下仅仅是罗列官网的

| 注释 | 说明 | 示例 |
| :----------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- |
| title | 必填 应用程序的名称。 | // @title Swagger Example API |
| version | 必填 提供应用程序API的版本。 | // @version 1.0 |
| description | 应用程序的简短描述。 | // @description This is a sample server celler server. |
| tag.name | 标签的名称。 | // @tag.name This is the name of the tag |
| tag.description | 标签的描述。 | // @tag.description Cool Description |
| tag.docs.url | 标签的外部文档的URL。 | // @tag.docs.url [https://example.com](https://example.com/) |
| tag.docs.description | 标签的外部文档说明。 | // @tag.docs.description Best example documentation |
| termsOfService | API的服务条款。 | // @termsOfService http://swagger.io/terms/ |
| contact.name | 公开的API的联系信息。 | // @contact.name API Support |
| contact.url | 联系信息的URL。 必须采用网址格式。 | // @contact.url http://www.swagger.io/support |
| contact.email | 联系人/组织的电子邮件地址。 必须采用电子邮件地址的格式。 | // @contact.email [support@swagger.io](mailto:support@swagger.io) |
| license.name | 必填 用于API的许可证名称。 | // @license.name Apache 2.0 |
| license.url | 用于API的许可证的URL。 必须采用网址格式。 | // @license.url http://www.apache.org/licenses/LICENSE-2.0.html |
| host | 运行API的主机(主机名或IP地址)。 | // @host [localhost:8080](http://localhost:8080/) |
| BasePath | 运行API的基本路径。 | // @BasePath /api/v1 |
| accept | API 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。 值必须如“[Mime类型](https://github.com/swaggo/swag/blob/master/README_zh-CN.md#mime类型)”中所述。 | // @accept json |
| produce | API可以生成的MIME类型的列表。值必须如“[Mime类型](https://github.com/swaggo/swag/blob/master/README_zh-CN.md#mime类型)”中所述。 | // @produce json |
| query.collection.format | 请求URI query里数组参数的默认格式:csv,multi,pipes,tsv,ssv。 如果未设置,则默认为csv。 | // @query.collection.format multi |
| schemes | 用空格分隔的请求的传输协议。 | // @schemes http https |
| externalDocs.description | Description of the external document. | // @externalDocs.description OpenAPI |
| externalDocs.url | URL of the external document. | // @externalDocs.url https://swagger.io/resources/open-api/ |
| x-name | 扩展的键必须以x-开头,并且只能使用json值 | // @x-example-key {"key": "value"} |

### 配置 Controller

```go
// 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)}
```

### 运行命令生成 docs

如果你写的注释格式没问题,此时你的项目根目录下会多出一个 docs 文件夹。

```csharp
swag init
```

### **配置文档** **handler**

最后则是在 router 中增加 swagger 的 handler 了。

在 main.go 或其他地方增加一个 handler.

```css
engine := gin.New()engine.GET("swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
```

### **访问测试**

项目运行起来后访问`ip:port/swagger/index.html` 即可看到 API 文档。

![go 项目集成Swagger 文档](https://apifox.com/apiskills/content/images/2023/07/image-282.png)Swagger 文档

[**更多流程参考**](https://github.com/swaggo/swag#getting-started)

鄂ICP备13000209号-1

鄂公网安备 42050602000277号