# 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)