乔克视界 乔克视界
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • DevOps
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档

乔克

云原生爱好者
首页
  • 运维
  • 开发
  • 监控
  • 安全
  • 随笔
  • Docker
  • Golang
  • Python
  • AIOps
  • DevOps
  • 心情杂货
  • 读书笔记
  • 面试
  • 实用技巧
  • 博客搭建
友链
关于
收藏
  • 分类
  • 标签
  • 归档
  • Docker

  • Golang

    • Golang基础知识

    • Golang进阶知识

    • Golang常用包

    • Gin框架

      • 安装
      • gin路由
      • 请求数据参数绑定
      • gin渲染
      • 使用模板渲染
      • 静态文件的使用
      • 数据渲染
      • gin重定向
      • gin同步和异步
      • go中间件
      • 会话保持
      • 文件上传
      • JWT的简单使用
      • 模板函数
      • Swagger
        • 安装
        • 写入注解
        • 生成 swagger 文件
        • 添加访问路由
        • 查看接口文档
        • 不定类型
      • API访问控制
      • 常见的应用中间件
      • 应用配置管理
      • 优雅停止与重启
      • 集成Casbin进行访问权限控制
  • AIOps

  • Python

  • DevOps

  • 专栏
  • Golang
  • Gin框架
乔克
2025-07-19
目录

Swagger

Swagger 是基于标准的 OpenAPI 规范进行设计的。只要按照这套规范编写注解或通过扫描代码生成注解,就能生成统一标准的接口文档和一系列 Swagger 工具。

# 安装

在项目目录下:

go get -u github.com/swaggo/swag/cmd/swag
go get -u github.com/swaggo/gin-swagger
go get -u github.com/swaggo/files
go get -u github.com/alecthomas/template
1
2
3
4

验证是否安装成功。

>swag -v
swag version v1.7.0
1
2

# 写入注解

在安装完 Swagger 关联库后,就需要项目里的 API 接口编写注解,以便后续在生成时能够正确地运行。

比如:

注解 描述
@Summary 摘要
@Produce API 可以产生的 MIME 类型的列表,可以将 MIME 简单理解为响应类型,例如 JSON、XML、HTML 等
@Tags 给 API 分组
@Param 参数格式,从左到右分别为:参数名,参数类型,数据类型,是否必填,注释
@Success 响应成功,从左到右分别为:状态码,参数类型,数据类型,注释
@Failure 响应失败,从左到右分别为:状态码,参数类型,数据类型,注释
@Router 路由,从左到右分别问:路由地址,HTTP 方法

比如 Tag 的 API:

type Tag struct {
}

func NewTag() Tag {
	return Tag{}
}

func (t Tag) Get(ctx *gin.Context) {}

// @Summary 获取多个标签
// @Produce json
// @Tags 标签
// @Param name query string false "标签名称" maxlength(100)
// @Param state query int false "状态" Enums(0, 1) default(1)
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} model.TagSwagger "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/tags [get]
func (t Tag) List(ctx *gin.Context) {}

// @Summary 新增标签
// @Produce json
// @Tags 标签
// @Param name body string true "标签名称" minlength(3) maxlength(100)
// @Param state body int false "状态" Enums(0, 1) default(1)
// @Param created_by body string true "创建者" minlength(3) maxlength(100)
// @Success 200 {object} model.Tag "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/tags [post]
func (t Tag) Create(ctx *gin.Context) {}

// @Summary 更新标签
// @Produce json
// @Tags 标签
// @Param id path int true "标签ID"
// @Param name body string true "标签名称" minlength(3) maxlength(100)
// @Param state body int false "状态" Enums(0, 1) default(1)
// @Param modified_by body string true "修改者" minlength(3) maxlength(100)
// @Success 200 {array} model.Tag "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/tags/{id} [put]
func (t Tag) Update(ctx *gin.Context) {}

// @Summary 删除标签
// @Produce json
// @Tags 标签
// @Param id path int true "标签ID"
// @Success 200 {object} model.Tag "成功"
// @Failure 400 {object} errcode.Error "请求错误"
// @Failure 500 {object} errcode.Error "内部错误"
// @Router /api/v1/tags/{id} [delete]
func (t Tag) Delete(ctx *gin.Context) {}

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

然后配置 MAIN 方法

// @title 博客系统
// @version 1.0
// @description 简单的博客系统
// @termsOfService https://github.com/qiaokebaba/blog_service

func main() {
	gin.SetMode(global.ServerSetting.RunMode)
	router := routers.NewRouter()
	s := &http.Server{
		Addr:              ":" + global.ServerSetting.HttpPort,
		Handler:           router,
		TLSConfig:         nil,
		ReadTimeout:       global.ServerSetting.ReadTimeout,
		ReadHeaderTimeout: 0,
		WriteTimeout:      global.ServerSetting.WriteTimeout,
		IdleTimeout:       0,
		MaxHeaderBytes:    1 << 20,
		TLSNextProto:      nil,
		ConnState:         nil,
		ErrorLog:          nil,
		BaseContext:       nil,
		ConnContext:       nil,
	}
	//global.Logger.Info("服务器启动成功,监听:")
	_ = s.ListenAndServe()

}
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

# 生成 swagger 文件

在编写完或更新完注解后,在项目跟目录下,执行以下命令:

> swag init
2021/02/03 11:43:40 Generate swagger docs....
2021/02/03 11:43:40 Generate general API Info, search dir:./
2021/02/03 11:43:41 Generating model.Tag
2021/02/03 11:43:41 Generating model.Model
2021/02/03 11:43:41 Generating errcode.Error
2021/02/03 11:43:41 create docs.go at docs\docs.go
2021/02/03 11:43:41 create swagger.json at docs\swagger.json
2021/02/03 11:43:41 create swagger.yaml at docs\swagger.yaml

1
2
3
4
5
6
7
8
9
10

可以看到在 docs 目录下,分别生成了docs.go、swagger.json、swagger.yaml文件。

# 添加访问路由

如何访问接口文件呢?直接添加一个路由即可,比如:

import (
	_ "code.coolops.cn/blog_services/docs"
	v1 "code.coolops.cn/blog_services/internal/routers/api/v1"
	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

func NewRouter() *gin.Engine {
	r := gin.New()
	r.Use(gin.Logger())
	r.Use(gin.Recovery())
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
	article := v1.NewArticle()
	tag := v1.NewTag()
	apiv1 := r.Group("/api/v1")
	{
		apiv1.POST("/tags", tag.Create)
		apiv1.DELETE("/tags/:id", tag.Delete)
		apiv1.PUT("/tags/:id", tag.Update)
		apiv1.PATCH("/tags/:id/state", tag.Update)
		apiv1.GET("/tags", tag.Get)
	}
	return r
}

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

# 查看接口文档

路由配置完成后,启动项目,即可在浏览器访问:http://127.0.0.1:8080/swagger/index.html,如下:

50b95e577c5b1ceb00bd05c72d0c4700 MD5

# 不定类型

在实际编写代码中,我们常常会遇到某个对象内的某个字段是 interface,并且这个字段的类型是不定的,即公共结构体,比如:

type Test struct{
	Username string
    Content interface{}
}
1
2
3
4

对于这种方式的,就没有特别好的注解方式,官方给出的建议是就是定义一个针对 Swagger 的对象,专门用于 Swagger 接口文档的展示。

比如:

type TagSwagger struct {
	List []*Tag
	Pager *app.Pager
}
1
2
3
4

然后将注解处改为如下:

// @Success 200 {object} model.TagSwagger "成功"
1

然后重新生成文件,只需执行以下命令

swag init
1

最后的效果如下:

d57abc0857f4307cbbc092f51aae5886 MD5

作者:乔克

本文链接:https://jokerbai.com

版权声明:本博客所有文章除特别声明外,均采用 署名-非商业性-相同方式共享 4.0 国际 (CC-BY-NC-SA-4.0) 许可协议。转载请注明出处!

上次更新: 2025/07/19, 09:17:41
模板函数
API访问控制

← 模板函数 API访问控制→

最近更新
01
使用 Generic Webhook Trigger 触发 Jenkins 多分支流水线自动化构建
07-19
02
使用Zadig从0到1实现持续交付平台
07-19
03
基于Jira的运维发布平台
07-19
更多文章>
Theme by Vdoing | Copyright © 2019-2025 乔克 | MIT License | 渝ICP备20002153号 |
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式