
企業工商數據API用哪種?
# - 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
除此此外我們還可以手動編譯:
cd 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查看.
# 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
其他安裝方式,例如二進制方式安裝或者容器方式安裝。
Docker 安裝方式
# 鏡像拉取
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
package main
?下添加通用API注釋, 注釋解析。package main
import (
"errors"
"net/http"
"github.com/gin-gonic/gin"
"github.com/swaggo/swag/example/celler/controller"
_ "github.com/swaggo/swag/example/celler/docs"
"github.com/swaggo/swag/example/celler/httputil"
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 http://swagger.io/terms/
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// @BasePath /api/v1
// @securityDefinitions.basic BasicAuth
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name Authorization
// @description Description for what is this security definition being used
// @securitydefinitions.oauth2.application OAuth2Application
// @tokenUrl https://example.com/oauth/token
// @scope.write Grants write access
// @scope.admin Grants read and write access to administrative information
// @securitydefinitions.oauth2.implicit OAuth2Implicit
// @authorizationUrl https://example.com/oauth/authorize
// @scope.write Grants write access
// @scope.admin Grants read and write access to administrative information
// @securitydefinitions.oauth2.password OAuth2Password
// @tokenUrl https://example.com/oauth/token
// @scope.read Grants read access
// @scope.write Grants write access
// @scope.admin Grants read and write access to administrative information
// @securitydefinitions.oauth2.accessCode OAuth2AccessCode
// @tokenUrl https://example.com/oauth/token
// @authorizationUrl https://example.com/oauth/authorize
// @scope.admin Grants read and write access to administrative information
func main() {
r := gin.Default()
c := controller.NewController()
v1 := r.Group("/api/v1")
{
admin := v1.Group("/admin") {
admin.Use(auth())
admin.POST("/auth", c.Auth)
}
// 路由分組
examples := v1.Group("/examples"){
examples.GET("ping", c.PingExample)
examples.GET("calc", c.CalcExample)
examples.GET("groups/:group_id/accounts/:account_id", c.PathParamsExample)
examples.GET("header", c.HeaderExample)
examples.GET("securities", c.SecuritiesExample)
examples.GET("attribute", c.AttributeExample)
}
}
// 關鍵點設置 Swagger 路由
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.Run(":8080")
}
func auth() gin.HandlerFunc {
return func(c *gin.Context) {
if len(c.GetHeader("Authorization")) == 0 {
httputil.NewError(c, http.StatusUnauthorized, errors.New("Authorization is required Header"))
c.Abort()
}
c.Next()
}
}
此外,一些通用API信息可以動態設置。生成的代碼包文檔導出SwaggerInfo變量,我們可以使用該變量以編程方式設置標題、描述、版本、主機和基本路徑。
package main
import (
"github.com/gin-gonic/gin"
"github.com/swaggo/files"
"github.com/swaggo/gin-swagger"
"./docs" // docs is generated by Swag CLI, you have to import it.
)
// @contact.name API Support
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
func main() {
// 以編程方式設置swagger信息
docs.SwaggerInfo.Title = "Swagger Example API"
docs.SwaggerInfo.Description = "This is a sample server Petstore server."
docs.SwaggerInfo.Version = "1.0"
docs.SwaggerInfo.Host = "petstore.swagger.io"
docs.SwaggerInfo.BasePath = "/v2"
docs.SwaggerInfo.Schemes = []string{"http", "https"}
r := gin.New()
// use ginSwagger middleware to serve the API docs
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
r.Run()
}
GET或者POST
請求, 有興趣的朋友請自行查看文檔。// 以下是一個使用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",
})
}
swag init
?命令生成 Swaager UI 所需的?swagger.json
?與?swagger.yaml
?.# 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
"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
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”} |
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 details will 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. |
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 |
溫馨提示: swag接受所有格式正確的MIME類型,即match \*/\*
,除此之外swag還接受一些MIME類型的別名,如下所示:
最新項目參考地址,由于時間推移(2023年6月13日 16:14:45)建議大家訪問查看最新注釋聲明:
https://github.com/swaggo/swag/blob/master/README.md#declarative-comments-format
描述: 此處是作者正在開發的一個內部項目,此處我為其添加上了swagger接口文檔,方便后續內部同事調用。
package 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
文件示例。
package routers
// router 目錄負責路由相關內容,如定義路由及路由處理函數,路由加載的中間件等
import (
"devopsapi/docs"
"devopsapi/handler/app"
"devopsapi/handler/webhook"
send "devopsapi/pkg/common"
"github.com/gin-gonic/gin"
swaggerfiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
)
// Load 中負責加載中間件 middlewares、路由 routes 和 handlers
func Load(r *gin.Engine, mw ...gin.HandlerFunc) *gin.Engine {
// 請求異常處理
r.NoRoute(send.HandleNotFound)
r.NoMethod(send.HandleNotFound)
// 前端項目靜態資源
r.StaticFile("/", "./static/dist/index.html")
r.StaticFile("/favicon.ico", "./static/dist/favicon.ico")
r.Static("/assets", "./static/dist/assets")
// 單路由
// r.GET("/app/version", app.Version)
// Swagger 對象方式設置基礎路徑
docs.SwaggerInfo.BasePath = "/api/v1"
// 路由組
_app := r.Group("/app")
{
_app.GET("/version", app.Version)
_app.POST("/restart", app.Restart)
}
_v1 := r.Group("/api/v1")
{
_v1.POST("/webhook/qywx", webhook.QYWXSendMsg)
_v1.POST("/webhook/dingtalk", webhook.DingtalkSendMsg)
_v1.POST("/webhook/email", webhook.EmailSendMsg)
}
// ginSwagger 路由處理
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
// 加載中間件
r.Use(mw...)
return r
}
Step 3.Go-Gin項目handler\webhook\qywx.go
文件示例,添加了swagger的接口注釋。
package 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的接口注釋。
type emailType struct {
Type string form:"type" json:"type" binding:"required" example:"text|html|file|tpl"
To []string form:"to" json:"to" binding:"required" example:"master@weiyigeek.top"
Cc []string form:"cc" json:"cc" example:"master@weiyigeek.top"
Subject string form:"subject" json:"subject" binding:"required" example:"郵件主題"
Body string form:"body" json:"body" binding:"required" example:"郵件內容"
File string form:"file" json:"file" example:"/app/storage/public/weiyigeek.jpg"
Filename string form:"filename" json:"filename" example:"weiyigeek-作者照片"
Template string form:"tpl" json:"tpl" example:"TemplateVerifiy"
}
// 使用企業郵箱發送郵件信息 (POST) 示例 Swagger
// @Summary 企業郵箱信息發送
// @Description 使用企業郵箱發送多種類型的郵件信息
// @Tags 消息通知
// @Accept json
// @Produce json
// @Param type query string true "發送類型"
// @Param body body emailType true "請求body"
// @Success 200 {string} EmailSendMsg
// @Security BasicAuth
// @Security API鑒權
// @Router /webhook/email [POST]
func EmailSendMsg(c *gin.Context) {
sendType := c.Query("type")
....... 此處略過n行代碼
}
Step 5.命令行進入到Go-Gin項目devopsapi
目錄中,執行?swag init
?生成 swagger-ui 所需文件, 生成完畢后便可運行該項目。
# PowerShell
cd devopsapi # 進入項目根路徑
&"$env:GOPATH/bin/swag" init -g ./main.go -o ./docs # 初始化文檔
# 2023/06/13 17:55:52 Generate swagger docs....
# 2023/06/13 17:55:52 Generate general API Info, search dir:./
# 2023/06/13 17:55:52 Generating webhook.emailType
# 2023/06/13 17:55:52 create docs.go at docs/docs.go
# 2023/06/13 17:55:52 create swagger.json at docs/swagger.json
# 2023/06/13 17:55:52 create swagger.yaml at docs/swagger.yaml
# 運行此app應用
PS D:\Study\Project\Go\devopsapi> go run .\main.go
Step 6.運行后訪問 http://127.0.0.1:8080/swagger/index.html
查看swagger接口文檔,效果如下所示,
除此之外,我們還可以使用swagger-UI進行在線模擬請求我們開發的接口,是不是非常方便呀!
本文至此完畢,更多技術文章,盡情等待下篇好文!
原文地址: https://blog.weiyigeek.top/2023/6-5-746.html
本文章轉載微信公眾號@全棧工程師修煉指南