go——Swagger使用

一. 为什么后端需要配置Swagger

        在前后端分离的项目中,后端配置swagger可以很好的帮助前端人员了解后端接口参数和数据传输。

        Swagger是一个用于设计,构建和文档化API的开源框架。在Go语言中,Swagger可以帮助后端开发人员快速创建和定义RESTful API,并提供自动生成接口文档的功能,这些文档包含了API的详细信息以及如何使用他们的说明。

RESTful API:

        RESTful是一个网络应用程序的设计风格,基于HTTP协议。使用XML或JSON格式定义统一标准接口。强调资源,统一接口,URL和无状态的设计风格。

        总的来说,RESTful就是一个资源定位,资源操作的风格。不是标准也不是协议,只是一种风格。

  • 资源:互联网所有的事务都可以抽象为资源
  • 资源操作:分为POST,DELETE,PUT,GET四种方法,使用不同的方法对资源进行操作(增,删,改,查)

传统风格与RESTful风格对比:

  • 传统风格:通过不同的参数实现不同的效果,方法单一。

http://127.0.0.1/item/queryItem.action?id=1 (查询,GET) http://127.0.0.1/item/saveItem.action (新增,POST) http://127.0.0.1/item/updateItem.action (更新,POST) http://127.0.0.1/item/deleteItem.action?id=1 (删除,GET或POST)

  • RESTful方式操作资源:通过不同的请求方式来实现不同的效果。

        如下:请求资源地址相同,但是功能不同。

http://127.0.0.1/item/1 (查询,GET)

http://127.0.0.1/item (新增,POST)

http://127.0.0.1/item (更新,PUT)

http://127.0.0.1/item/1 (删除,DELETE)

        现在的网络上基本上全是RESTful风格。

二. 基本使用

        2.1 安装

        安装最新swagger库:

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

        测试是否安装成功:

        2.2 使用步骤

         以Gin框架为例,需要用到gin-swagger库。安装:

go get -u github.com/swaggo/gin-swagger //gin-swagger中间件
go get -u github.com/swaggo/files //swagger嵌入文件

         gin-swagger使用步骤:

  • 按照swagger要求给接口代码添加声明式注释,具体参照声明式注释格式。
  • 使用swag工具扫描代码自动生成API接口文档数据
  • 使用gin-swagger渲染在线接口文档页面

        2.3 添加注释

        在程序入口main函数上以注释的方式写下项目相关介绍信息。

// @title Swagger Example API
// @version 1.0
// @description this is a sample server celler server
// @termsOfService https://www.swagger.io/terms/

// @contact.name 氷
// @contact.url http://www.swagger.io/support
// @contact.email abc.xyz@qq.com

// @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
  • title:文档标题
  • version:版本
  • description,termsOfService,contact.name contact.url,contact.email都是一些声明,可不写。
  • license:是必须的
  • host,BasePath:如果你想直接swagger调试API,这两项需要填写正确。前者为服务文档的端口,ip。后者为基础路径,像我们这里就是"/api/v1"。
  • 在原文档中还有securityDefinitions.basic , securityDefinitions.apikey等,这些都是
    用来做认证的。
        在代码中处理请求的接口函数(通常位于controller层),按如下方式注释。
// @Summary 测试sayHello
// @Description 向你说hello
// @Tags 测试
// @Accept json
// @Param name query string true "人名"
// @Success 200 {string} string "{"msg": "hello wy"}"
// @Failure 400 {string} string "{"msg": "who are you"}"
// @Router /hello [get]

通用API信息:

注释描述
AcceptAccept字段仅适用于带有request body的请求,例如POST、PUT和PATCH。只有使用这些请求方法的接口才需要定义接收的 MIME 类型列表。
Produce定义接口返回的 MIME 类型列表。

MIME类型

别名MIME Type
json    application/json
xml     text/xml
plain    text/plain
html     text/html
mpfd    multipart/form-data
x-www-form-urlencodedapplication/x-www-form-urlencoded
json-apiapplication/vnd.api+json
json-streamapplication/x-json-stream
octet-stream application/octet-stream
png image/png
jpeg image/jpeg
gif image/gif

API操作:

  • @Summary    接口功能的简要概述。
  • @Description    接口的详细说明。
  • @Tags    接口的标签列表,可以有多个标签,每个标签用英文的逗号分隔。这样接口会按照标签进行分类。
  • @Param    接口接收的数据,参数用空格分隔。参数分别是:“参数名” “参数类型” “数据类型” “是否必须” “参数的描述” “其它属性”。
  • @Success    接口的成功响应语法格式:“响应的状态码” “响应参数类型” “响应数据类型” “描述信息”。
  • @Failure    接口的故障响应语法格式:“响应的状态码” “响应参数类型” “响应数据类型” “描述信息”。
  • @Response    与@Success和@Failure的作用相同。
  • @Router    接口的路由定义,用空格隔开路径和请求方法。 path [httpMethod]
  • @Security    定义接口的安全性

Param

参数类型

  • query:该类型参数直接拼接在URL中。URL中后面的参数
  • path:该类型参数一般组合在URL中。如:/api/v1/:id
  • header:
  • body
  • formData:该类型参数一般是POST,PUT方法所用。

数据类型

  • string (string)
  • integer (int, uint, uint32, uint64)
  • number (float32)
  • boolean (bool)
  • object (struct)

        如果你是上传文件可以使用file,但参数类型一定是formData

其它属性:

        除了上面这些属性外,我们还可以为该参数填写一些额外的属性,如枚举,默认值,值范围等。

枚举
// @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" mininum(1) maxinum(10)

 设置默认值
 // @Param default query string false "string default" default(A)

 Success/Failure

响应状态码:也就是200,400,500这些

响应参数类型:整个数据类型。string表示字符串,object表示自定义类型,anrry表示数组

响应数据类型:具体当个数据的类型。

描述信息:其它说明。

例如:

表示响应状态码200 响应是参数字符串类型,数据也是字符串类型
// @Success 200 {string} string

表示响应状态码200 响应是参数自定义类型,数据也是自定义类型为main包中的File类型
// @Success 200 {object} main.File

表示响应状态码200 响应是参数数组类型,数据类型表示数组中单个元素类型为main包中的File类型
//@Success 200 {anrry} main.File

表示响应状态码200 响应是参数字符串类型,数据类型字符串表示的是json类型
 // @Success 200 {string} json ""

Router 

        格式:

        不需要加基础路径。

//Router /path/to/handle [http方法]

        2.4 测试示例

自动生成swagger文档

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

// @title Swagger Example API
// @version 1.0
// @description this is a sample server celler server
// @termsOfService https://www.swagger.io/terms/

// @contact.name 氷
// @contact.url http://www.swagger.io/support
// @contact.email abc.xyz@qq.com

// @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
func main() {
	r := gin.Default()
	//注册swagger api相关路由
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	v := r.Group("/api/v1")
	{
		v.GET("/hello", helloHandler)
	}
	r.Run()
}

// helloHandler
// @Summary 测试sayHello
// @Description 向你说hello
// @Tags 测试
// @Accept json
// @Param name query string true "人名"
// @Success 200 {string} string "{"msg": "hello wy"}"
// @Failure 400 {string} string "{"msg": "who are you"}"
// @Router /hello [get]
func helloHandler(c *gin.Context) {
	name := c.Query("name")

	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{"msg": "who are you"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": "hello" + name})
}

        在main.go目录下执行swag init就可以当前目录下自动生成文档: 

        然后我们在main.go中导入自动生成的docs包,运行: 

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"

	_ "sample-app/swagger/docs"
)

//...

        浏览器打开http://127.0.0.1:8080/swagger/index.html,我们可以看到对于接口文档。

         介绍:

         点击Try it out就可以进行测试:

        2.5 多个tags

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"

	_ "sample-app/swagger/docs"
)

// @title Swagger Example API
// @version 1.0
// @description this is a sample server celler server
// @termsOfService https://www.swagger.io/terms/

// @contact.name 氷
// @contact.url http://www.swagger.io/support
// @contact.email abc.xyz@qq.com

// @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
func main() {
	r := gin.Default()
	//注册swagger api相关路由
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))

	v := r.Group("/api/v1")
	{
		v.GET("/hello", helloHandler)
		v.GET("/hello1", helloHandler1)

		v.GET("/load", loadHandler)
	}
	r.Run()
}

// @Summary 测试sayHello
// @Description 向你说hello
// @Tags 测试
// @Accept json
// @Param name query string true "人名"
// @Success 200 {string} string "{"msg": "hello wy"}"
// @Failure 400 {string} string "{"msg": "who are you"}"
// @Router /hello [get]
func helloHandler(c *gin.Context) {
	name := c.Query("name")

	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{"msg": "who are you"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": "hello" + name})
}

// @Summary 测试sayHello other
// @Description 向你说hello
// @Tags 测试
// @Accept json
// @Param name query string true "人名"
// @Success 200 {string} string "{"msg": "hello wy"}"
// @Failure 400 {string} string "{"msg": "who are you"}"
// @Router /hello1 [get]
func helloHandler1(c *gin.Context) {
	name := c.Query("name")

	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{"msg": "who are you"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": "hello" + name})
}

// @Summary 加载账号密码
// @Description 加载账号密码
// @Tags 加载
// @Accept json
// @Param id query string true "账号"
// @Param passwd query string true "密码"
// @Success 200 {string} json "{"msg": "id:asd passwd:2123"}"
// @Failure 400 {string} json "{"msg": "账号或密码错误"}"
// @Router /load [get]
func loadHandler(c *gin.Context) {
	name := c.Query("id")
	passwd := c.Query("passwd")

	if name == "" || passwd == "" {
		c.JSON(http.StatusBadRequest, gin.H{"msg": "账号或密码错误"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": "id:" + name + " passwd:" + passwd})
}

         重新在命令行输入swag init。生成swag文档,运行main.go。访问为:http://127.0.0.1:8080/swagger/index.html

三. 优化 

        swagger文档只是我们测试的时候需要,当我们产品上线后,接口文档是不应该给用户的,并且带有接口文档的包会大很多(swaggo是直接build到二进制中的)

        想处理这种情况,我们可以在编译的时候优化一下。比如利用build -tags来控制是否编译文档。

        go build -tags 是一个 Go 语言的命令行选项,用于在构建过程中启用或禁用特定的编译标签。这些标签通常用于控制代码的特定行为,例如启用或禁用某些功能、优化等

        比如:下面表示,tag1tag2 是你想要启用的标签。你可以根据需要添加更多的标签,用空格分隔。

go build -tags "tag1 tag2"

         在你的 Go 代码中,你可以使用 // +build 注释来指定哪些文件应该在特定的标签下编译。

        在main.go声明swagHandler变量,并在该参数不为空时才加入路由。编译带docs标签的swagHandler才不会为空。才可以使用swagger接口文档。

        docs.go 

//go:build docs
// +build docs

package main

import (
	_ "sample-app/swagger/docs"

	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
)

func init() {
	swagHandler = ginSwagger.WrapHandler(swaggerFiles.Handler)
}

        main.go

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"

	_ "sample-app/swagger/docs"
)

var swagHandler gin.HandlerFunc

// @title Swagger Example API
// @version 1.0
// @description this is a sample server celler server
// @termsOfService https://www.swagger.io/terms/

// @contact.name 氷
// @contact.url http://www.swagger.io/support
// @contact.email abc.xyz@qq.com

// @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
func main() {
	r := gin.Default()

	//不为空,才会加入swagger路由
	if swagHandler != nil {
		//注册swagger api相关路由
		r.GET("/swagger/*any", swagHandler)
	}

	v := r.Group("/api/v1")
	{
		v.GET("/hello", helloHandler)
	}
	r.Run()
}

// @Summary 测试sayHello
// @Description 向你说hello
// @Tags 测试
// @Accept json
// @Param name query string true "人名"
// @Success 200 {string} string "{"msg": "hello wy"}"
// @Failure 400 {string} string "{"msg": "who are you"}"
// @Router /hello [get]
func helloHandler(c *gin.Context) {
	name := c.Query("name")

	if name == "" {
		c.JSON(http.StatusBadRequest, gin.H{"msg": "who are you"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"msg": "hello" + name})
}

        带标签比不带标签编译出来的文件大小大很多。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/771473.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JVM 堆内存结构 年轻代 老年代

堆内存 内存划分 对于大多数应用,Java 堆是 Java 虚拟机管理的内存中最大的一块,被所有线程共享。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数据都在这里分配内存。 为了进行高效的垃圾回收,虚拟机把堆内存…

关键路径——C语言(理论)

关键路径,是项目网络中从起始事件到终止事件的最长路径,决定了项目的最短完成时间。 关键路径中的任务没有任何可调整的余地,如果任何一个任务被延迟,整个项目的完成时间也会被延迟。 假设我们现在有一个图:把图的边…

高二的他已通过NOI保送北大了,让我们一起了解他的信息学奥赛学习经历吧!!!

相信关注本号的各位,对于信息学奥赛已经不陌生了,部分同学也已经开始踏入信息学的旅程,但前路茫茫,让我们一起看看已经取得成就的同学的经历吧。 今天要介绍的这位同学,是来自深圳中学的高二某班的欧阳达晟同学&#x…

failed to lazily initialize a collection of role,解决Hibernate查询报错

Hibernate报错: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.jiuqi.gov.common.attatchment.entity.AttachmentEntity.properties, could not initialize proxy - no Session at org.hibernate.co…

docker私有仓库harbor部署

docker私有仓库harbor部署 概述 Docker 官方镜像源被中国大陆政府封锁,导致无法在中国大陆的计算机上直接使用 Docker 拉取镜像,导致使用者一下子手足无措了,的确一开始会有很大的影响,为了应对这种影响我们可以自己构建私有仓库&…

昇思25天学习打卡营第4天|yulang

今天主要了解了数据集 Dataset,主要包含了:数据集加载、数据集迭代、数据集常用操作、 可随机访问数据集、可迭代数据集、生成器。对于生成器很好理解,用代码来造数据,可以动态地生成数据。主要作用数据集通常被用于训练模型

12个视觉艺术分类

视觉设计可以按照多种方式进行分类,这些分类通常基于设计的目的、风格或应用场景。本文为大家介绍12种视觉设计,分别是平面设计、标志设计、包装设计、用户界面设计 (UI Design)、用户体验设计 (UX Design)、插图设计、网页设计、动画设计、展览设计、环…

云服务出现故障这样处理

无法连接云服务器 服务器远程无法连接时,可通过7ECloud控制台进行连接。 常见故障现象 1、ping不通 2、ping丢包 3、部分端口telnet不通 4、全部端口telnet不通 5、广告、弹窗植入 6、域名无法访问IP访问正常 常见故障原因 1、云服务器过期、关机或者EIP被…

阿里云物联网应用层开发:第三部分,微信小程序和web客户端实现

文章目录 哔哩哔哩视频教程1、阿里云物联网平台对接微信小程序2、阿里云物联网平台对接web客户端2-1MQTT服务器编写2-2 web端Servlet部分编写备注哔哩哔哩视频教程 【阿里云物联网综合开发,STM32+ESP8266+微信小程序+web客户端一篇教程详细讲解】 https://www.bilibili.com/v…

Java中读写文件内容乱码/BufferedReader读文件内容乱码/OutputStreamWriter设置编码集

1、问题概述? 在项目中我们经常会将例如日志信息放入到txt(任意后缀)文档中,然后在项目中通过弹框等形式查看直接的查看这些文档中的信息,然后有时候会出现乱码的情况。 这个时候我们就需要设置写入和写出时候的编码集情况。 2、解决方案 当然编码集的问题,还需要从项目…

ONLYOFFICE8.1版本桌面编辑器的测评(您的私人办公室)

ONLYOFFICE官网链接:ONLYOFFICE - 企业在线办公应用软件 | ONLYOFFICE 在线PDF查看器和转换器 | ONLYOFFICE​​​​​​在线办公套件 | ONLYOFFICE 一,引言 在数字化浪潮中,高效、便捷、安全的办公工具对现代职场至关重要。今天,…

MySQL5.7下载及安装详细教程

我下载的是MySQL 5.7.43 ,以下是详细下载安装过程 一、下载过程步骤 1、进入官方网站:https://www.mysql.com/ 2、首页滑到最下面,找到MySQL Community server 3、选择你想要的版本和电脑对应配置进行下载 4、下载完后,保存解…

【TB作品】20以内加减法训练机,ATMEGA128单片机,Proteus仿真

题目 7 :玩具电子琴 基于单片机设计一能够发出中音八个音阶的音乐信号的电子琴,能够实现弹奏和音符显示功 能。 具有 8 个音阶按键,每按下一个按键时,所对应的 LED 点亮,音符进行显示。 具体要求如下: &…

tampermonkey插件下载国家标准文件

#创作灵感# 最近在一个系统招标正文中看到了一些国家标准,想要把文章下载下来,方便查阅,但是“国家标准全文公开系统”网站只提供了在线预览功能,没有提供下载功能,但是公司又需要文件,在网上找了一些办法&…

矩阵置零解题

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]示例 2: 输入&…

用户资料门户的构建

1. 需求背景 老的页面停止维护了,且老旧, 功能单一,且页面分散. 急需做功能集成的平台化建设原先的用户资料查询没有做权限管控, 每一次查询都会消耗我们组的人力资源. 2. 项目介绍 2.1. 项目地址 服务地址: [公司内网服务(略)] 工蜂地址: [公司内网仓库(略)] 2.2 项目的价…

Spring Security基本源码解析(超精细版)

一、基本源码解析 1.1 UsernamePasswordAuthenticationFilter 用户名称和密码的过滤器 浏览器发送用户名称和密码 ----》 经过过滤器「UsernamePasswordAuthenticationFitler」 1.2 UsernamePasswordAuthenticationFilter核心方法 重写父类「AbstractAuthenticationProcessing…

数据在内存中的存储方式

🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:C语言 目录 前言 一、整数的存储 二、大小端字节序及其判断 1.什么是大小端 2.为什么有大小端 3.用c语言编写程序判断大小端 三、浮点数的存储 1.浮点数…

第7章:Electron文件系统操作(2)

7.2 文件对话框 Electron 提供了 dialog 模块用于显示文件打开和保存对话框。 7.2.1 显示文件打开对话框 主进程代码: const { app, BrowserWindow, ipcMain, dialog } require(electron); const path require(path);let mainWindow;const createMainWindow …

【Unity学习笔记】A*寻路算法

文章目录 图寻路算法BFS广度优先算法DFS深度优先贪心算法 引入权重Dijkstra算法 A*算法C#实现步骤 Unity中的A*算法A*优化建议 图 图的知识盘点 pathfinding 作为一名计算机专业的学生,对于图这种数据结构也是烂熟于心了。图是一种包含了多个结点的数据结构&…