zoukankan      html  css  js  c++  java
  • gin-swagger生成API文档

    github地址:https://github.com/swaggo/gin-swagger

     

    下载安装cmd/swag命令工具包

    先下载cmd包,才能执行相关命令

    go get -u github.com/swaggo/swag/cmd/swag

    我开始没成功,后来进入$GOPATH/bin/ 目录执行go get github.com/swaggo/swag/cmd/swag ,在bin目录下生成一个swag.exe文件,把$GOPATH/bin/ 添加到Path环境变量才算成功

    执行初始化命令

    swag init  // 注意,一定要和main.go处于同一级目录

    初始化命令,在根目录生成一个docs文件夹

    • docs/docs.go

    示例程序

    复制代码
    package main
    
    import (
        "apiwendang/controller"
        _ "apiwendang/docs"
        "github.com/gin-gonic/gin"
        swaggerFiles "github.com/swaggo/files"
        ginSwagger "github.com/swaggo/gin-swagger"
    )
    
    
    // @title Docker监控服务
    // @version 1.0
    // @description docker监控服务后端API接口文档
    
    // @contact.name API Support
    // @contact.url http://www.swagger.io/support
    
    // @license.name Apache 2.0
    // @license.url http://www.apache.org/licenses/LICENSE-2.0.html
    
    // @host 127.0.0.1:9009
    // @BasePath
    func main() {
        r := gin.New()
    
        r.Use(Cors())
        //url := ginSwagger.URL("http://localhost:8080/swagger/doc.json") // The url pointing to API definition
        r.POST("/test/:id", controller.Test)
        r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    
        r.Run(":9009")
    }
    
    
    func Cors() gin.HandlerFunc {
        return func(c *gin.Context) {
            c.Header("Access-Control-Allow-Origin", "*")
            c.Next()
        }
    }
    复制代码

    再次执行初始化命令

    swag init  // 注意,一定要和main.go处于同一级目录

    初始化命令,在根目录生成一个docs文件夹,内含三个文件

    • docs/docs.go
    • swagger.json
    • swagger.yaml

    访问swagger文档:http://localhost:9009/swagger/index.html

    ====

    API操作

    复制代码
    // @Summary 接口概要说明
    // @Description 接口详细描述信息
    // @Tags 用户信息   //swagger API分类标签, 同一个tag为一组
    // @accept json  //浏览器可处理数据类型,浏览器默认发 Accept: */*
    // @Produce  json  //设置返回数据的类型和编码
    // @Param id path int true "ID"    //url参数:(name;参数类型[query(?id=),path(/123)];数据类型;required;参数描述)
    // @Param name query string false "name"
    // @Success 200 {object} Res {"code":200,"data":null,"msg":""}  //成功返回的数据结构, 最后是示例
    // @Failure 400 {object} Res {"code":200,"data":null,"msg":""}
    // @Router /test/{id} [get]    //路由信息,一定要写上
    复制代码

    如果参数是body

    // @Param user body models.User true "user"

    1. 返回字符串

    复制代码
    // @Summary 测试接口
    // @Description 描述信息
    // @Success 200 {string} string    "ok"
    // @Router / [get]
    func Test(ctx *gin.Context)  {
        ctx.JSON(200, "ok")
    }
    复制代码

     2. 返回gin.H

    复制代码
    // @Summary 测试接口
    // @Description 描述信息
    // @Success 200 {object} gin.H
    // @Router / [get]
    func Test(ctx *gin.Context)  {
        ctx.JSON(200, gin.H{
            "code":200,
        })
    }
    复制代码

    如果直接返回gin.H这种json结构,要用@Success 200 {object} gin.H,但是这种编译很慢,最好还是返回一种固定的结构体

    3. 返回固定struct结构体

    复制代码
    type Res struct {
        Code int `json:"code"`
        Data interface{} `json:"data"`
        Msg string `json:"msg"`
    }
    func returnMsg(ctx *gin.Context, code int, data interface{}, msg string) {
        ctx.JSON(200, Res{
            Code:code,
            Data:data,
            Msg:msg,
        })
    }
    
    // @Summary 测试接口
    // @Description 描述信息
    // @Success 200 {object} Res {"code":200,"data":null,"msg":""}
    // @Router / [get]
    func Test(ctx *gin.Context)  {
        ctx.JSON(200, Res{
            Code:200,
            Data:nil,
            Msg:"",
        })
    }
    复制代码

     POST请求:

    复制代码
    models/user.go
      
    type User struct {
        ID   int    `json:"id"`
        Name string `json:"name"`
    }
    ==================
    
    type Res struct {
        Code int `json:"code"`
        Data interface{} `json:"data"`
        Msg string `json:"msg"`
    }
    func returnMsg(ctx *gin.Context, code int, data interface{}, msg string) {
        ctx.JSON(200, Res{
            Code:code,
            Data:data,
            Msg:msg,
        })
    }
    
    
    func Test1(ctx *gin.Context)  {
        returnMsg(ctx, 500, "aaa", "bbb")
    }
    
    // @Summary 接口概要说明
    // @Description 接口详细描述信息
    // @Tags 测试
    // @Security Bearer
    // @Produce  json
    // @Param id path int true "ID"
    // @Param user body models.User true "user"
    // @Success 200 {object} Res {"code":200,"data":null,"msg":""}
    // @Router /test/{id} [post]
    func Test(ctx *gin.Context)  {
        fmt.Println(ctx.Param("id"))
        var input models.User
        if err := ctx.ShouldBindJSON(&input); err!=nil{
            returnMsg(ctx, 402, nil, err.Error())
            return
        }
        fmt.Println(input)
        returnMsg(ctx, 200, "aaa", "bbb")
    }
    复制代码

    如果出现错误:Undocumented   TypeError: Failed to fetch

    查看具体错误信息,浏览器F12,发现是跨域问题:

    Failed to load http://127.0.0.1:9009/test/2: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9009' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

    设置允许跨域就OK了

    简单版本:

    复制代码
    func Cors() gin.HandlerFunc {
        return func(c *gin.Context) {
            c.Header("Access-Control-Allow-Origin", "*")
            c.Next()
        }
    }
    复制代码

    复杂的可以根据实际需求添加:

    复制代码
    func Cors() gin.HandlerFunc {
        return func(c *gin.Context) {
            method := c.Request.Method  
            origin := c.Request.Header.Get("Origin")
            var headerKeys []string
            for k, _ := range c.Request.Header {
                headerKeys = append(headerKeys, k)
            }
            headerStr := strings.Join(headerKeys, ", ")
            if headerStr != "" {
                headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers, %s", headerStr)
            } else {
                headerStr = "access-control-allow-origin, access-control-allow-headers"
            }
            if origin != "" {
                c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
                c.Header("Access-Control-Allow-Origin", "*")                                       // 这是允许访问所有域
                c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE") //服务器支持的所有跨域请求的方法,为了避免浏览次请求的多次'预检'请求
                //  header的类型
                c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")
                //              允许跨域设置                                                                                                      可以返回其他子段
                c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析
                c.Header("Access-Control-Max-Age", "172800")                                                                                                                                                           // 缓存请求信息 单位为秒
                c.Header("Access-Control-Allow-Credentials", "false")                                                                                                                                                  //  跨域请求是否需要带cookie信息 默认设置为true
                c.Set("content-type", "application/json")                                                                                                                                                              // 设置返回格式是json
            }
    
            //放行所有OPTIONS方法
            //if method == "OPTIONS" {
            //    c.JSON(http.StatusOK, "Options Request!")
            //}
            if method == "OPTIONS" {
                c.AbortWithStatus(204)
                return
            }
            // 处理请求
            c.Next() //  处理请求
        }
    }
    复制代码

    https://www.ctolib.com/swaggo-swag.html

    https://github.com/swaggo/swag

    原文 https://www.cnblogs.com/zhzhlong/p/11800787.html

  • 相关阅读:
    overflow妙用--去除默认滚动条,内容仍可滚动
    call()与构造函数的运用
    this与super
    构造方法
    多态
    抽象类与接口
    面向对象的基本特征
    类与对象
    面向过程与面向对象
    java自动拆装箱
  • 原文地址:https://www.cnblogs.com/brady-wang/p/15355571.html
Copyright © 2011-2022 走看看