# gin中使用swagger
# 安装
## 使用如下命令安装swag命令
➜ go go install github.com/swaggo/swag/cmd/swag@latest
go: downloading github.com/ghodss/yaml v1.0.0
go: downloading github.com/urfave/cli/v2 v2.3.0
go: downloading golang.org/x/net v0.0.0-20220722155237-a158d28d115b
go: downloading golang.org/x/text v0.3.7
go: downloading golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
go: downloading github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
go: downloading github.com/russross/blackfriday/v2 v2.0.1
go: downloading github.com/shurcooL/sanitized_anchor_name v1.0.0
➜ go
## 查看是否安装成功
➜ go swag -v
swag version v1.8.7
# 注释
给代码添加注释,注释主要分为两类,一类是全局注释信息,一般放在入口函数main上。另一类是api注释信息,放在每个每个api处理函数上面
# 全局注释
# 示例
// @Title gin framework layout
// @Version 0.0.1
// @Description gin framework layout
// @host localhost:8888
// @securityDefinitions.apikey Authorization
// @in header
// @name Authorization
// @description api request authorization
func main() {
core.New().ListenAndServe(router.RegisterRoutersFunc())
}
# 说明
注释 | 说明 |
---|---|
Title | 应用标题 |
Version | 应用版本 |
Description | 应用描述 |
TermsOfService | 服务条款 |
Contact.name | 联系名称 |
Contact.url | 联系url |
Contact.email | 联系email |
License.name | 协议名称 |
License.url | 协议地址 |
Host | 服务host |
BasePath | 基础path |
# 文档
General API Info (opens new window)
# Api注释
# 示例
// @Summary 登录
// @Description 登录接口
// @Tags 用户
// @Accept json
// @Produce json
// @Param data body UserLoginRequest true "登录凭证"
// @Response 200 {object} global.Response{data=UserLoginResponseData}
// @Router /api/user/login [post]
func (u *UserController) Login(c *gin.Context) {
var req UserLoginRequest
if u.ShouldBindJSON(c, &req) {
u.JSON(c, u.Svc.Login(&req))
}
}
// @Summary 退出登录
// @Description 退出登录接口
// @Tags 用户
// @Accept json
// @Produce json
// @Security Authorization
// @Response 200 {object} global.Response{}
// @Router /api/user/logout [get]
func (u *UserController) Logout(c *gin.Context) {
u.JSON(c, u.Svc.Logout(c.GetUint64("Id")))
}
// @Summary 当前登录信息
// @Description 获取登录信息接口
// @Tags 用户
// @Accept json
// @Produce json
// @Security Authorization
// @Response 200 {object} global.Response{data=UserCurrentResponseData}
// @Router /api/user/current [get]
func (u *UserController) Current(c *gin.Context) {
u.JSON(c, u.Svc.Current(c.GetUint64("Id"), c.GetBool("RefreshAuthorization")))
}
// @Summary 修改密码
// @Description 修改密码接口
// @Tags 用户
// @Accept json
// @Produce json
// @Security Authorization
// @Param data body ChangePasswordRequest true "修改密码数据"
// @Response 200 {object} global.Response{data=global.UpdateResponseData}
// @Router /api/user/changePassword [post]
func (u *UserController) ChangePassword(c *gin.Context) {
req := &ChangePasswordRequest{}
if u.ShouldBindJSON(c, req) {
req.Id = c.GetUint64("Id")
u.JSON(c, u.Svc.ChangePassword(req))
}
}
// @Summary 用户信息
// @Description 用户信息接口
// @Tags 用户
// @Accept json
// @Produce json
// @Security Authorization
// @param id query uint64 true "id"
// @Response 200 {object} global.Response{data=UserData}
// @Router /api/user [get]
func (u *UserController) Get(c *gin.Context) {
u.Controller.Get(c, &global.GetRequest{}, &UserData{}, false)
}
// @Summary 用户列表
// @Description 用户列表接口
// @Tags 用户
// @Accept json
// @Produce json
// @Security Authorization
// @param account query string false "账号"
// @param username query string false "姓名"
// @param role query string false "角色"
// @param status query int false "状态"
// @param current query int true "当前页数"
// @param pageSize query int true "页数量"
// @Response 200 {object} global.Response{data=[]UserData}
// @Router /api/user/list [get]
func (u *UserController) List(c *gin.Context) {
req := &UserListRequest{}
if u.ShouldBindQuery(c, req) {
u.JSON(c, u.Svc.List(req, &[]UserData{}, false))
}
}
// @Summary 新增用户
// @Description 新增用户接口
// @Tags 用户
// @Accept json
// @Produce json
// @Security Authorization
// @Param data body UserInsertRequest true "新增用户信息"
// @Response 200 {object} global.Response{data=global.InsertResponseData}
// @Router /api/user [post]
func (u *UserController) Insert(c *gin.Context) {
req := &UserInsertRequest{}
u.CreatedBy(c, req)
if u.ShouldBindJSON(c, req) {
u.JSON(c, u.Svc.Insert(req))
}
}
// @Summary 更新用户
// @Description 更新用户接口
// @Tags 用户
// @Accept json
// @Produce json
// @Security Authorization
// @Param data body UserUpdateRequest true "更新用户信息"
// @Response 200 {object} global.Response{data=global.UpdateResponseData}
// @Router /api/user [put]
func (u *UserController) Update(c *gin.Context) {
u.Controller.Update(c, &UserUpdateRequest{})
}
// @Summary 删除用户
// @Description 删除用户接口
// @Tags 用户
// @Accept json
// @Produce json
// @Security Authorization
// @Param data body global.RemovesRequest true "删除用户id"
// @Response 200 {object} global.Response{data=global.RemoveResponseData}
// @Router /api/user [delete]
func (u *UserController) Removes(c *gin.Context) {
// request
req := &global.RemovesRequest{}
u.ShouldBindJSON(c, req)
// login id
loginId := c.GetUint64("Id")
for _, id := range req.Ids {
if id == loginId {
u.JSON(c, Err_User_Can_Not_Remove_self_Response)
return
} else if id == 1 {
u.JSON(c, Err_User_Can_Not_Remove_Super_Response)
return
}
// remove login flag
u.Svc.DelLoginStatus(id)
}
u.JSON(c, u.Svc.Remove(req))
}
# 说明
注释 | 说明 |
---|---|
Description | Api行为的详细说明 |
Id | 用于标识操作的唯一字符串。在所有API操作中必须是唯一的 |
Tags | 每个API操作的标签列表,用逗号分隔。 |
Summary | Api的简短摘要 |
Accept | api可以使用的MIME类型列表。值必须与Mime类型下的描述一致 |
Produce | api可以生成的MIME类型列表。值必须与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 | 用空格分隔的响应. return code,{param type},data type,comment |
Router | 路由. path,[httpMethod] |
# 文档
API Operation (opens new window)
# 生成文档
# 格式化swag注释
➜ gin-framework-layout git:(master) swag fmt
➜ gin-framework-layout git:(master)
# 生成swag文档
## --parseDependency, --pd 在依赖文件夹内解析go文件,默认禁用(默认值:false)
## --parseInternal 在内部包中解析go文件,默认禁用(默认值:false)
➜ gin-framework-layout git:(master) swag init --parseDependency --parseInternal
2022/11/03 16:35:57 Generate swagger docs....
2022/11/03 16:35:57 Generate general API Info, search dir:./
2022/11/03 16:35:59 Generating user.UserLoginRequest
2022/11/03 16:35:59 Generating global.Response
2022/11/03 16:35:59 Generating user.UserLoginResponseData
2022/11/03 16:35:59 Generating user.UserCurrentResponseData
2022/11/03 16:35:59 Generating user.ChangePasswordRequest
2022/11/03 16:35:59 Generating global.UpdateResponseData
2022/11/03 16:35:59 Generating user.UserData
2022/11/03 16:35:59 Generating global.Data
2022/11/03 16:35:59 Generating global.CreatedBy
2022/11/03 16:35:59 Generating global.UpdatedBy
2022/11/03 16:35:59 Generating user.UserInsertRequest
2022/11/03 16:35:59 Generating global.InsertResponseData
2022/11/03 16:35:59 Generating user.UserUpdateRequest
2022/11/03 16:35:59 Generating global.RemovesRequest
2022/11/03 16:35:59 Generating global.RemoveResponseData
2022/11/03 16:35:59 create docs.go at docs/docs.go
2022/11/03 16:35:59 create swagger.json at docs/swagger.json
2022/11/03 16:35:59 create swagger.yaml at docs/swagger.yaml
# 文档路径
➜ gin-framework-layout git:(master) cd docs
➜ docs git:(master) tree
.
├── docs.go
├── swagger.json
└── swagger.yaml
0 directories, 3 files
# 路由
package router
import (
"net/http"
"github.com/goweb/gin-framework-core/global"
"github.com/gin-gonic/gin"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
_ "github.com/goweb/gin-framework-layout/docs"
)
func RegisterHealthyCheckRouter(g *gin.Engine) {
// ping router
g.GET("/healthyCheck", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"msg": "ok",
})
})
}
func RegisterSwaggerRouter(g *gin.Engine) {
// debug mode run swagger server
if global.Config.Sys.Mode == gin.DebugMode || global.Config.Sys.Mode == gin.TestMode {
// swagger router
g.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
}
}
# go mod tidy下载相关依赖包
➜ gin-framework-layout git:(master) go mod tidy
# 访问
swagger地址:http://localhost:8888/swagger/index.html (opens new window)