最近需要使用Go写一个Web API项目,可以使用Beego与Gin来写此类项目,前文 使用Beego创建API项目并自动化文档介绍了使用Beego来创建的Web API项目并自动化文档的方法。本文就介绍一下使用Gin来编写Web API项目并自动化文档。

一、创建项目

在创建Beego项目时,可以使用Beego的Bee命令来创建项目;而Gin没有类似的程序或者命令来创建项目,所以需要手动创建一个Go项目,新建一个目录,并进入该目录创建项目:

1$ mkdir api
2$ cd api
3$ go mod init api
4$ go mod tidy

二、添加代码

创建好项目后,即可使用VSCode或者Goland打开目录,开始工作了。项目结构可以参考Beego的Model-Controls方式:

 1$ tree
 2.
 3├── controls
 4│   └── user.go
 5├── go.mod
 6├── go.sum
 7├── main.go
 8├── models
 9│   └── user.go
10└── routers
11    └── router.go
12
134 directories, 6 files

这里直接把源码贴出来:

main.go

 1package main
 2
 3import (
 4	"api/routers"
 5
 6	"github.com/gin-gonic/gin"
 7)
 8
 9func main() {
10	r := gin.Default()
11	routers.InitRouters(r)
12	r.Run(":8080")
13}

routers/router.go

 1package routers
 2
 3import (
 4	"api/controls"
 5
 6	"github.com/gin-gonic/gin"
 7)
 8
 9func InitRouters(r *gin.Engine) {
10	r.Group("v1").GET("users", controls.GetAllUsers)
11}

models/user.go

 1package models
 2
 3var (
 4	UserList map[string]*User
 5)
 6
 7type User struct {
 8	Id       string
 9	Username string
10	Password string
11	Profile  Profile
12}
13
14type Profile struct {
15	Gender  string
16	Age     int
17	Address string
18	Email   string
19}
20
21func init() {
22	UserList = make(map[string]*User)
23	u := User{"user_888888", "witton", "888888", Profile{"male", 20, "成都", "witton@163.com"}}
24	UserList["user_888888"] = &u
25}
26
27func GetAllUsers() map[string]*User {
28	return UserList
29}

controls/user.go

 1package controls
 2
 3import (
 4	"api/models"
 5	"net/http"
 6
 7	"github.com/gin-gonic/gin"
 8)
 9
10func GetAllUsers(c *gin.Context) {
11	c.JSON(http.StatusOK, models.GetAllUsers())
12}

添加好代码后,执行:

1$ go mod tidy

运行项目后,可以在浏览器中访问:http://127.0.0.1:8080/v1/users

在这里插入图片描述

就可以看到结果了。

三、自动化文档

使用Beego创建API项目并自动化文档中说的一样,为了方便测试,需要引入swagger来自动化文档。

1. 安装最新swag

使用下面的命令安装最新的swag

1go install github.com/swaggo/swag/cmd/swag@latest

2. 编写swag注释

修改controls/user.go,在GetAllUsers函数上添加注释:

 1package controls
 2
 3import (
 4	"api/models"
 5	"net/http"
 6
 7	"github.com/gin-gonic/gin"
 8)
 9
10// @Summary 获取所有用户
11// @Produce  json
12// @Success 200 {object} models.User
13// @Router /v1/users [get]
14func GetAllUsers(c *gin.Context) {
15	c.JSON(http.StatusOK, models.GetAllUsers())
16}

关于注释的格式,可以参考: https://gitee.com/acrowise/swag https://github.com/swaggo/swag/blob/master/README_zh-CN.md

3. 生成文档

使用swag init命令生成文档:

1$ swag init
22024/05/06 14:36:57 Generate swagger docs....
32024/05/06 14:36:57 Generate general API Info, search dir:./
42024/05/06 14:36:57 create docs.go at docs/docs.go
52024/05/06 14:36:57 create swagger.json at docs/swagger.json
62024/05/06 14:36:57 create swagger.yaml at docs/swagger.yaml

生成文档后,会在根目录下创建一个docs目录,所有生成的文件都放在里面。

 1$ tree
 2.
 3├── controls
 4│   └── user.go
 5├── docs
 6│   ├── docs.go
 7│   ├── swagger.json
 8│   └── swagger.yaml
 9├── go.mod
10├── go.sum
11├── main.go
12├── models
13│   └── user.go
14└── routers
15    └── router.go
16
175 directories, 9 files

4. 添加路由

routers/router.go中添加路由:

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

routers/router.go完整代码:

 1package routers
 2
 3import (
 4	"api/controls"
 5
 6	_ "api/docs"
 7
 8	"github.com/gin-gonic/gin"
 9	swaggerFiles "github.com/swaggo/files"
10	ginSwagger "github.com/swaggo/gin-swagger"
11)
12
13func InitRouters(r *gin.Engine) {
14	r.Group("v1").GET("users", controls.GetAllUsers)
15	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
16}

需要注意的是:swaggerFiles已经改名了,不再是"github.com/swaggo/gin-swagger/swaggerFiles",如果导入"github.com/swaggo/gin-swagger/swaggerFiles",则会报错:

1go: finding module for package github.com/swaggo/gin-swagger/swaggerFiles
2go: api/routers imports
3        github.com/swaggo/gin-swagger/swaggerFiles: module github.com/swaggo/gin-swagger@latest found (v1.6.0), but does not contain package github.com/swaggo/gin-swagger/swaggerFiles 

需要导入"github.com/swaggo/files"

5. 运行测试

执行go mod tidy下载依赖后再启动项目,在浏览器中访问:http://127.0.0.1:8080/swagger/index.html,即可看到页面:

在这里插入图片描述

测试一下API:

在这里插入图片描述

可以看到正常的结果。