3.Gin之Go语言Web框架进阶开发实践
|[TOC]
0x00 在你使用Gin开发Web时添加swagger
1.swagger简单介绍
官网介绍: Swagger工具是由原始“Swagger”规范背后的团队开发的。Swagger提供了最强大和最容易使用的工具,以充分利用OpenAPI规范。
使用 Swagger 开源和专业工具集简化用户、团队和企业的 API 开发, 并且帮助开发者完善接口设计,接口开发、接口文档、接口测试、API模拟和虚拟化、以及接口治理与接口监控。
官网地址: https://swagger.io/
文档地址: https://swagger.io/docs/specification/2-0/basic-structure/
接口规范: https://swagger.io/resources/open-api/
此处由于是在Golang中的Web框架Gin中使用Swagger,所以在下一章节中暂时介绍如何在Golang的Web框架Gin中使用Swagger。
2.swag、gin-swagger项目安装
描述: go-swagger 是一个主要生成或分析源代码的工具,我们可以使用 go-swagger
工具为Gin项目使用Swagger 2.0自动生成RESTful API文档。
项目功能
- Basic Structure
- API Host and Base Path
- Paths and Operations
- Describing Parameters
- Describing Request Body
- Describing Responses
- MIME Types
- Authentication
- Basic Authentication
- API Keys
- Adding Examples
- File Upload
- Enums
- Grouping Operations With Tags
- Swagger Extensions (开发中)
项目地址:
支持的 Web Frameworks:
gin
echo
buffalo
net/http
gorilla/mux
go-chi/chi
flamingo
fiber
atreugo
hertz
安装实践
1.首先需要安装Go语言环境下 swagger
相关工具,可以使用以下命令安装,参考地址 ( https://goswagger.io/install.html)1
2
3
4
5
6
7
8
9
10# Swagger 2.0 implementation for go
# - go-swagger 工具为 Go 程序生成 swagger 相关文档 (手动配yaml文件)
# 从Go 1.17开始,不赞成使用Go get安装可执行文件建议使用 go install
go install github.com/go-swagger/go-swagger/cmd/swagger@latest
# 不建议
# go get -u github.com/go-swagger/go-swagger/cmd/swagger
# - swag 工具将 Go 注释转换为 Swagger 文档 2.0,使您可以快速与现有的 Go 项目集成(使用 Swagger UI,此处用于go-gin项目
go install github.com/swaggo/swag/cmd/swag@latest
# go get -u github.com/swaggo/swag/cmd/swag
除此此外我们还可以手动编译:1
2cd D:\Study\Go\package\pkg\mod\github.com\swaggo\swag@v1.16.1\cmd\swag
go build -o swag.exe ./main.go
2.此处由于我是 windows 其安装目录如下, 通过CMD命令或者PowerShell查看.1
2
3
4
5
6
7
8
9
10# CMD
> dir "%GOPATH%/bin/" /B
swag
swagger.exe
# PowerShell
> ls $env:GOPATH/bin
Directory: D:\Study\Go\package\bin
-a--- 2023/6/12 14:59 14539264 swag.exe
-a--- 2023/6/13 9:49 24419840 swagger.exe
其他安装方式,例如二进制方式安装或者容器方式安装。
- 二进制方式: Go-Swagger 二进制文件下载 [ https://github.com/go-swagger/go-swagger/tags ] ,swag 二进制文件下载 [ https://github.com/swaggo/swag/releases ] ,请注意对应系统版本 .
- Docker 安装方式
1
2
3
4
5
6# 镜像拉取
docker pull quay.io/goswagger/swagger
# 在 Winwdows 中即在Go开发项目下执行
docker run --rm -it --env GOPATH=/go -v %CD%:/go/src -w /go/src quay.io/goswagger/swagger
# 在 Linux 中
docker run --rm -it --env GOPATH=/go -v $pwd:/go/src -w /go/src quay.io/goswagger/swagger
3.如何在Gin使用Swagger生成API接口文档?
1.在你的Go-gin项目main.go代码中的 package main
下添加通用API注释, 注释解析。
1 | package main |
此外,一些通用API信息可以动态设置。生成的代码包文档导出SwaggerInfo变量,我们可以使用该变量以编程方式设置标题、描述、版本、主机和基本路径。
1 | package main |
2.在控制器(路由处理函数)代码中使用Swagger注释来定义API文档, 此处只是展示两种情况GET或者POST
请求, 有兴趣的朋友请自行查看文档。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83// 以下是一个使用Swagger注释的示例:
// GET 请求示例
// @Summary get request example
// @Description get request example
// @Tags example
// @Accept json
// @Produce plain
// @Param val1 query int true "used for calc"
// @Param enumstring query string false "string enums" Enums(A, B, C)
// @Param enumint query int false "int enums" Enums(1, 2, 3)
// @Param enumnumber query number false "int enums" Enums(1.1, 1.2, 1.3)
// @Param string query string false "string valid" minlength(5) maxlength(10)
// @Param int query int false "int valid" minimum(1) maximum(10)
// @Param default query string false "string default" default(A)
// @Param example query string false "string example" example(string)
// @Param collection query []string false "string collection" collectionFormat(multi)
// @Param extensions query []string false "string collection" extensions(x-example=test,x-nullable)
// @Param group_id path int true "Group ID"
// @Param group_id path int true "Group ID"
// @Param Authorization header string true "Authentication header"
// @Success 200 {string} string "answer"
// @Failure 400 {string} string "ok"
// @Failure 404 {string} string "ok"
// @Failure 500 {string} string "ok"
// @Router /examples/groups/{group_id}/accounts/{account_id} [get]
func (c *Controller) AttributeExample(ctx *gin.Context) {
// URL路由参数 /{group_id}
groupID, err := strconv.Atoi(ctx.Param("group_id"))
if err != nil {
httputil.NewError(ctx, http.StatusBadRequest, err)
return
}
accountID, err := strconv.Atoi(ctx.Param("account_id"))
if err != nil {
httputil.NewError(ctx, http.StatusBadRequest, err)
return
}
// Header 参数
auth := ctx.GetHeader("Authorization")
// URL请求参数 ?
ctx.String(http.StatusOK, fmt.Sprintf("enumstring=%s enumint=%s enumnumber=%s string=%s int=%s default=%s group_id=%d account_id=%d Authorization=%s",
ctx.Query("enumstring"),
ctx.Query("enumint"),
ctx.Query("enumnumber"),
ctx.Query("string"),
ctx.Query("int"),
ctx.Query("default"),
groupID,
accountID,
auth,
))
}
// POST 请求示例引入接口安全校验机制
// models/model.go
package model
type Account struct {
id string `form:"id" json:"id" binding:"required" example:"100001"`
User string `form:"user" json:"user" binding:"required" example:"weiyigeek.top"`
Addr string `form:"addr" json:"addr" example:"重庆市南岸区学府大道"`
Hobby []string `form:"hobby" json:"hobby" example:"计算机,烹饪,运动"`
age int `form:"age" json:"age" example:"25"`
}
// @Summary post request example
// @Description post request example
// @Tags example
// @Accept json
// @Produce plain
// @Param message body model.Account true "Account Info"
// @Success 200 {string} string "success"
// @Failure 500 {string} string "fail"
// @Security ApiKeyAuth
// @Security OAuth2Implicit[admin, write]
// @Router /examples/post [post]
func (c *Controller) PostExample(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H {
"post": "ping",
})
}
3.使用 swag init
命令生成 Swaager UI 所需的 swagger.json
与 swagger.yaml
.1
2
3
4
5
6
7
8# Powershell
> &"$env:GOPATH/bin/swag" init -g .\main.go
2023/06/13 10:40:11 Generate swagger docs....
2023/06/13 10:40:11 Generate general API Info, search dir:./
.....
2023/06/13 10:40:11 create docs.go at docs/docs.go
2023/06/13 10:40:11 create swagger.json at docs/swagger.json
2023/06/13 10:40:11 create swagger.yaml at docs/swagger.yaml
4.执行"go run ./main.go"
命令运行此Go gin项目,并使用浏览器浏览到 http://localhost:8080/swagger/index.html
站点, 您将看到Swagger 2.0 Api文档
示例代码: https://github.com/swaggo/swag/tree/master/example/celler
4.swag 项目声明性注释格式
1) 通用声明注释
annotation | description | example |
---|---|---|
title | Required. The title of the application. | // @title Swagger Example API |
version | Required. Provides the version of the application API. | // @version 1.0 |
description | A short description of the application. | // @description This is a sample server celler server. |
tag.name | Name of a tag. | // @tag.name This is the name of the tag |
tag.description | Description of the tag | // @tag.description Cool Description |
tag.docs.url | Url of the external Documentation of the tag | // @tag.docs.url https://example.com |
tag.docs.description | Description of the external Documentation of the tag | // @tag.docs.description Best example documentation |
termsOfService | The Terms of Service for the API. | // @termsOfService http://swagger.io/terms/ |
contact.name | The contact information for the exposed API. | // @contact.name API Support |
contact.url | The URL pointing to the contact information. MUST be in the format of a URL. | // @contact.url http://www.swagger.io/support |
contact.email | The email address of the contact person/organization. MUST be in the format of an email address. | // @contact.email support@swagger.io |
license.name | Required. The license name used for the API. | // @license.name Apache 2.0 |
license.url | A URL to the license used for the API. MUST be in the format of a URL. | // @license.url http://www.apache.org/licenses/LICENSE-2.0.html |
host | The host (name or ip) serving the API. | // @host localhost:8080 |
BasePath | The base path on which the API is served. | // @BasePath /api/v1 |
accept | A list of MIME types the APIs can consume. Note that Accept only affects operations with a request body, such as POST, PUT and PATCH. Value MUST be as described under Mime Types. | // @accept json |
produce | A list of MIME types the APIs can produce. Value MUST be as described under Mime Types. | // @produce json |
query.collection.format | The default collection(array) param format in query,enums:csv,multi,pipes,tsv,ssv. If not set, csv is the default. | // @query.collection.format multi |
schemes | The transfer protocol for the operation that separated by spaces. | // @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 | The extension key, must be start by x- and take only json value | // @x-example-key {“key”: “value”} |
2) 接口操作注释
annotation | description |
---|---|
description | A verbose explanation of the operation behavior. |
description.markdown | A short description of the application. The description will be read from a file. E.g. `@description.markdown detailswill load details.md` |
id | A unique string used to identify the operation. Must be unique among all API operations. |
tags | A list of tags to each API operation that separated by commas. |
summary | A short summary of what the operation does. |
accept | A list of MIME types the APIs can consume. Note that Accept only affects operations with a request body, such as POST, PUT and PATCH. Value MUST be as described under Mime Types. |
produce | A list of MIME types the APIs can produce. Value MUST be as described under Mime Types. |
param | Parameters that separated by spaces. param name ,param type ,data type ,is mandatory? ,comment attribute(optional) |
security | Security to each API operation. |
success | Success response that separated by spaces. return code or default ,{param type} ,data type ,comment |
failure | Failure response that separated by spaces. return code or default ,{param type} ,data type ,comment |
response | As same as success and failure |
header | Header in response that separated by spaces. return code ,{param type} ,data type ,comment |
router | Path definition that separated by spaces. path ,[httpMethod] |
x-name | The extension key, must be start by x- and take only json value. |
x-codeSample | Optional Markdown usage. take file as parameter. This will then search for a file named like the summary in the given folder. |
deprecated | Mark endpoint as deprecated. |
3) 接口安全认证注释
annotation | description | parameters | example |
---|---|---|---|
securitydefinitions.basic | Basic auth. | // @securityDefinitions.basic BasicAuth | |
securitydefinitions.apikey | API key auth. | in, name, description | // @securityDefinitions.apikey ApiKeyAuth |
securitydefinitions.oauth2.application | OAuth2 application auth. | tokenUrl, scope, description | // @securitydefinitions.oauth2.application OAuth2Application |
securitydefinitions.oauth2.implicit | OAuth2 implicit auth. | authorizationUrl, scope, description | // @securitydefinitions.oauth2.implicit OAuth2Implicit |
securitydefinitions.oauth2.password | OAuth2 password auth. | tokenUrl, scope, description | // @securitydefinitions.oauth2.password OAuth2Password |
securitydefinitions.oauth2.accessCode | OAuth2 access code auth. | tokenUrl, authorizationUrl, scope, description | // @securitydefinitions.oauth2.accessCode OAuth2AccessCode |
parameters annotation | example |
---|---|
in | // @in header |
name | // @name Authorization |
tokenUrl | // @tokenUrl https://example.com/oauth/token |
authorizationurl | // @authorizationurl https://example.com/oauth/authorize |
scope.hoge | // @scope.write Grants write access |
description | // @description OAuth protects our entity endpoints |
支持的 Mime 类型 / 参数(Param) 类型 / 数据(Data)类型
温馨提示: swag接受所有格式正确的MIME类型,即match \*/\*
,除此之外swag还接受一些MIME类型的别名,如下所示:
最新项目参考地址,由于时间推移(2023年6月13日 16:14:45)建议大家访问查看最新注释声明:
https://github.com/swaggo/swag/blob/master/README.md#declarative-comments-format
5.实践内部Go-Gin项目接入Swagger
描述: 此处是作者正在开发的一个内部项目,此处我为其添加上了swagger接口文档,方便后续内部同事调用。
- Step 1.Go-Gin项目 main.go 文件示例, 即 Swagger 通用注释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85package main
// @title devopsapi
// @version v1.1
// @description 安全运维中心API接口
// @termsOfService https://weiyigeek.top/terms
// @contact.name 开发者【WeiyiGeek】
// @contact.url http://weiyigeek.top/support
// @contact.email master@weiyigeek.top
// @externalDocs.description DevOpsApi 外部文档的描述
// @externalDocs.url https://swagger.io/resources/open-api/
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host 127.0.0.1:8080
// @BasePath /api/v1
// @schemes http https
// @securityDefinitions.basic BasicAuth
// $ echo -n weiyigeek:123456 | base64
// d2VpeWlnZWVrOjEyMzQ1Ng==
// @securityDefinitions.apikey API鉴权
// @in header
// @name Authorization
// @description Description for what is this security definition being used
func main() {
// 指定 gin 运行模式
gin.SetMode(global.App.Mode)
// 返回一个新的空白Engine实例
r := gin.New()
// 设置日志中间件
r.Use(middleware.Logger())
// 加载自定义路由
router.Load(r)
// 使用 graceful 管理 Gin 服务从而优雅的停止
srv := &graceful.Server{
Timeout: 10 * time.Second,
Server: &http.Server{
// Gin运行的监听端口
Addr: fmt.Sprintf("%s:%d", global.App.Host, global.App.Port),
// 要调用的处理程序,http.DefaultServeMux如果为nil
Handler: r,
// MaxHeaderBytes控制服务器解析请求标头的键和值(包括请求行)时读取的最大字节数 (通常情况下不进行设置)
MaxHeaderBytes: 1 << 20,
},
}
// 开启一个goroutine启动服务 启动 HTTP Server
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()
// 在一个新的goroutine中调用给定的函数
// 等待中断信号
quit := make(chan os.Signal)
// kill 默认会发送 syscall.SIGTERM 信号
// kill -2 发送 syscall.SIGINT 信号,我们常用的Ctrl+C就是触发系统SIGINT信号
// kill -9 发送 syscall.SIGKILL 信号,但是不能被捕获,所以不需要添加它
// signal.Notify把收到的 syscall.SIGINT或syscall.SIGTERM 信号转发给quit
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 此处不会阻塞
<-quit // 阻塞在此,当接收到上述两种信号时才会往下执行
log.Println("Shutdown Server ...")
// 创建一个 5 秒的超时上下文
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 关闭 HTTP Server
// // 5秒内优雅关闭服务(将未处理完的请求处理完再关闭服务),超过5秒就超时退出
if err := srv.Shutdown(ctx); err != nil {
log.Fatal("Server Shutdown:", err)
}
log.Println("Server exiting")
}
- Step 2.Go-Gin项目
routers\router.go
文件示例。
1 | package routers |
Step 3.Go-Gin项目
handler\webhook\qywx.go
文件示例,添加了swagger的接口注释。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62package webhook
import (
send "devopsapi/pkg/common"
"devopsapi/pkg/global"
"devopsapi/pkg/util/webhooks"
"fmt"
"log"
"github.com/gin-gonic/gin"
)
type qywxCommonType struct {
Key string `form:"key" json:"key" binding:"required"`
Type string `form:"type" json:"type" binding:"required"`
Msg string `form:"msg" json:"msg" binding:"required"`
User string `form:"user" json:"user"`
}
type qywxCustomMarkdownType struct {
Key string `form:"key" json:"key" binding:"required"`
Type string `form:"type" json:"type" binding:"required"`
Title string `form:"title" json:"title" binding:"required"`
Project string `form:"project" json:"project" binding:"required"`
Msg string `form:"msg" json:"msg" binding:"required"`
UrlText string `form:"urltext" json:"urltext"`
UrlAddr string `form:"urladdr" json:"urladdr"`
User string `form:"user" json:"user"`
}
type qywxImageType struct {
Key string `form:"key" json:"key" binding:"required"`
Type string `form:"type" json:"type" binding:"required"`
ImgData string `form:"imgdata" json:"imgdata" binding:"required"`
ImgMd5 string `form:"imgmd5" json:"imgmd5" binding:"required"`
}
// 使用企业微信机器人发送信息 (GET)示例 Swagger
// @Summary 企业微信机器人信息发送
// @Description 使用企业微信机器人发送多种类型信息到对应群聊
// @Tags 消息通知
// @Accept application/json
// @Produce application/json
// @Param key query string true "鉴权Key"
// @Param type query string true "消息类型"
// @Param msg query string true "发送的消息"
// @Param user query string false "接收者手机或名称"
// @Param title query string false "消息标题"
// @Param project query string false "消息主题"
// @Param urltext query string false "消息连接文本"
// @Param urladdr query string false "消息连接"
// @Param imgdata query string false "图片base64数据"
// @Param imgmd5 query string false "图片MD5值"
// @Success 200 {string} QYWXSendMsg
// @Router /webhook/qywx [POST]
func QYWXSendMsg(c *gin.Context) {
qywx_key := c.Query("key")
qywx_url := fmt.Sprintf("%s%s", global.WebHook.Qywechat, qywx_key)
msg_type := c.Query("type")
....... 此处略过n行代码
}Step 4.Go-Gin项目
handler\webhook\email.go
文件示例,添加了swagger的接口注释。
1 | type emailType struct { |
- Step 5.命令行进入到Go-Gin项目
devopsapi
目录中,执行swag init
生成 swagger-ui 所需文件, 生成完毕后便可运行该项目。
1 | # PowerShell |
- Step 6.运行后访问
http://127.0.0.1:8080/swagger/index.html
查看swagger接口文档,效果如下所示,
除此之外,我们还可以使用swagger-UI进行在线模拟请求我们开发的接口,是不是非常方便呀!
你好看友,欢迎关注博主微信公众号哟! ❤
这将是我持续更新文章的动力源泉,谢谢支持!(๑′ᴗ‵๑)
温馨提示: 未解锁的用户不能粘贴复制文章内容哟!
方式1.请访问本博主的B站【WeiyiGeek】首页关注UP主,
将自动随机获取解锁验证码。
Method 2.Please visit 【My Twitter】. There is an article verification code in the homepage.
方式3.扫一扫下方二维码,关注本站官方公众号
回复:验证码
将获取解锁(有效期7天)本站所有技术文章哟!
@WeiyiGeek - 为了能到远方,脚下的每一步都不能少
欢迎各位志同道合的朋友一起学习交流,如文章有误请在下方留下您宝贵的经验知识,个人邮箱地址【master#weiyigeek.top】
或者个人公众号【WeiyiGeek】
联系我。
更多文章来源于【WeiyiGeek Blog - 为了能到远方,脚下的每一步都不能少】, 个人首页地址( https://weiyigeek.top )
专栏书写不易,如果您觉得这个专栏还不错的,请给这篇专栏 【点个赞、投个币、收个藏、关个注、转个发、赞个助】,这将对我的肯定,我将持续整理发布更多优质原创文章!。
最后更新时间:
文章原始路径:_posts/编程世界/Go/Gin/3.Gin之Go语言Web框架进阶开发实践.md
转载注明出处,原文地址:https://blog.weiyigeek.top/2023/6-5-746.html
本站文章内容遵循 知识共享 署名 - 非商业性 - 相同方式共享 4.0 国际协议