• 【转】YApi结合swag管理和生成go项目restful API文档


    原文:https://blog.csdn.net/tuobicui6522/article/details/102980653

    swag命令安装:

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




    swag命令对应的github库:https://github.com/swaggo/swag

     用yapi在线调用接口测试

    aaa

    -----------------------------------------

    YApi结合swag管理go项目API文档

    准备
    什么是OpenAPI?Swagger是什么?
    安装和了解swag
    YApi教程
    docker部署YApi
    项目demo
    ├── controller
    │ ├── accounts.go
    │ └── controller.go
    ├── docs
    │ ├── docs.go
    │ ├── swagger.json
    │ └── swagger.yaml
    ├── go.mod
    ├── httputil
    │ └── error.go
    ├── main.go
    └── model
    └── account.go

    main.go

    package main

    import (
    "demo/controller"
    _ "demo/docs"

    "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 demo 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

    func main() {
    r := gin.Default()

    c := controller.NewController()

    v1 := r.Group("/api/v1")
    {
    accounts := v1.Group("/accounts")
    {
    accounts.GET(":id", c.ShowAccount)
    accounts.POST("", c.AddAccount)
    }
    }
    // 先用swag init 生成docs目录
    // http://localhost:8080/swagger/index.html 可以看swagger ui的文档
    r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
    r.Run(":8080")
    }


    controller/controller.go

    package controller

    // Controller example
    type Controller struct {
    }

    // NewController example
    func NewController() *Controller {
    return &Controller{}
    }

    // Message example
    type Message struct {
    Message string `json:"message" example:"message"`
    }

    controller/accounts.go

    package controller

    import (
    "demo/httputil"
    "demo/model"
    "net/http"
    "strconv"

    "github.com/gin-gonic/gin"
    )

    // ShowAccount godoc
    // @Summary Show a account
    // @Description get string by ID
    // @Tags accounts
    // @Accept json
    // @Produce json
    // @Param id path int true "Account ID"
    // @Success 200 {object} model.Account
    // @Failure 400 {object} httputil.HTTPError
    // @Failure 404 {object} httputil.HTTPError
    // @Failure 500 {object} httputil.HTTPError
    // @Router /accounts/{id} [get]
    func (c *Controller) ShowAccount(ctx *gin.Context) {
    id := ctx.Param("id")
    aid, err := strconv.Atoi(id)
    if err != nil {
    httputil.NewError(ctx, http.StatusBadRequest, err)
    return
    }
    account, err := model.AccountOne(aid)
    if err != nil {
    httputil.NewError(ctx, http.StatusNotFound, err)
    return
    }
    ctx.JSON(http.StatusOK, account)
    }

    // AddAccount godoc
    // @Summary Add a account
    // @Description add by json account
    // @Tags accounts
    // @Accept json
    // @Produce json
    // @Param account body model.AddAccount true "Add account"
    // @Success 200 {object} model.Account
    // @Failure 400 {object} httputil.HTTPError
    // @Failure 404 {object} httputil.HTTPError
    // @Failure 500 {object} httputil.HTTPError
    // @Router /accounts [post]
    func (c *Controller) AddAccount(ctx *gin.Context) {
    var addAccount model.AddAccount
    if err := ctx.ShouldBindJSON(&addAccount); err != nil {
    httputil.NewError(ctx, http.StatusBadRequest, err)
    return
    }
    if err := addAccount.Validation(); err != nil {
    httputil.NewError(ctx, http.StatusBadRequest, err)
    return
    }
    // Name以外的字段仅用来演示
    account := model.Account{
    Name: addAccount.Name,
    }
    lastID, err := account.Insert()
    if err != nil {
    httputil.NewError(ctx, http.StatusBadRequest, err)
    return
    }
    account.ID = lastID
    ctx.JSON(http.StatusOK, account)
    }


    httputil/error.go


    package httputil

    import "github.com/gin-gonic/gin"

    // NewError example
    func NewError(ctx *gin.Context, status int, err error) {
    er := HTTPError{
    Code: status,
    Message: err.Error(),
    }
    ctx.JSON(status, er)
    }

    // HTTPError example
    type HTTPError struct {
    Code int `json:"code" example:"400"`
    Message string `json:"message" example:"status bad request"`
    }


    model/account.go

    package model

    import (
    "errors"
    "fmt"

    uuid "github.com/satori/go.uuid"
    )

    // Account example
    type Account struct {
    ID int `json:"id" example:"1" format:"int64"`
    Name string `json:"name" example:"account name"`
    UUID uuid.UUID `json:"uuid" example:"550e8400-e29b-41d4-a716-446655440000" format:"uuid"`
    }

    // example
    var (
    ErrNameInvalid = errors.New("name is empty")
    ErrNoRow = errors.New("no rows in result set")
    )

    // AddAccount example
    // Name以外的字段仅用来测试 struct tag 的作用
    type AddAccount struct {
    Name string `json:"name" example:"Tom" format:"string" binding:"required" minLength:"1" maxLength:"16"` // 用户名
    Age int `json:"age" example:"10" binding:"required" minimum:"1" maximum:"150" default:"10"` // 年龄
    Height float64 `json:"height" example:"1.80" binding:"required" minimum:"0.0" maximum:"9.99"` // 身高,单位米
    Status string `json:"status" enums:"healthy,ill"` // 状态
    }

    // Validation example
    func (a AddAccount) Validation() error {
    switch {
    case len(a.Name) == 0:
    return ErrNameInvalid
    default:
    return nil
    }
    }

    // AccountOne example
    func AccountOne(id int) (Account, error) {
    for _, v := range accounts {
    if id == v.ID {
    return v, nil
    }
    }
    return Account{}, ErrNoRow
    }

    // Insert example
    func (a Account) Insert() (int, error) {
    accountMaxID++
    a.ID = accountMaxID
    a.Name = fmt.Sprintf("account_%d", accountMaxID)
    accounts = append(accounts, a)
    return accountMaxID, nil
    }

    var accountMaxID = 3
    var accounts = []Account{
    {ID: 1, Name: "account_1"},
    {ID: 2, Name: "account_2"},
    {ID: 3, Name: "account_3"},
    }


    swag生成API文档
    在项目根目录下执行以下命令生成docs目录

    swag init
    1
    YApi管理项目的API的文档
    打开localhost:40001登录YApi

    在个人空间下创建一个test分组,组长填自己的用户名好了

    在test分组下创建一个项目demo

    导入上面生成的docs/swagger.json文件,如图


    查看导入的接口

     

     

     


    在上图可以看到,model.AddAccount结构体附属的struct tag 和字段的注释已经变成文档的一部分了

    同时还可以像postman一样测试接口,其他功能就不说了,留待你们自己挖掘


    总结
    在go项目中,开发人员只要把代码的注解写好,然后用swag生成相关文件,YApi导入json文件,整个项目的接口管理变的清晰简单。不过文档没有swagger ui展示的那么详细,可以看情况搭配使用。
    ————————————————
    版权声明:本文为CSDN博主「米兰的小铁匠1943」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/tuobicui6522/article/details/102980653

  • 相关阅读:
    iOS之App Store上架被拒Legal
    iOS之解决崩溃Collection <__NSArrayM: 0xb550c30> was mutated while being enumerated.
    iOS之延时执行(睡眠)的几种方法
    iOS之UILabel的自动换行
    iOS之开发中一些相关的路径以及获取路径的方法
    iOS之绘制虚线
    iOS之判断手机号码、邮箱格式是否正确
    iOS之计算上次日期距离现在多久, 如 xx 小时前、xx 分钟前等
    iOS之开发中常用的颜色及其对应的RGB值
    method invocation
  • 原文地址:https://www.cnblogs.com/oxspirt/p/16631056.html
Copyright © 2020-2023  润新知