Generate API spec using GO / Gin gin-swagger

Preface

This article summarizes the insights for using the gin-swagger library to generate API specifications for Gin products. gin-swagger repository link swagger-banner.png

Create a product for testing

Create a folder

//In any directory
$ mkdir use_swagger && cd use_swagger

Initialize go mod

$ go mod init use_swagger

Library installation

$ go get -u github.com/gin-gonic/gin
$ go get -u github.com/swaggo/swag/cmd/swag
$ go get -u github.com/swaggo/gin-swagger
$ go get -u github.com/swaggo/files

Check the version after the installation is completed.

$ swag -v
swag version v1.6.7

Current directory structure

|-- use_swagger
|-- |-- go.mod

Added API specifications to the product

Create a main.go file under the ʻuse_swagger` directory

$ touch main.go

Before addition

main.go


package main

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

func main() {
	r := gin.New()	
	r.GET("/test", test)	
	r.Run()
}

func test(c *gin.Context){
	c.JSON(http.StatusOK, gin.H{ "msg": "ok"})
}

If you access http: // localhost: 8080 / test after starting the server, simple Json data will be returned. キャプチャ.PNG

After addition

main.go


package main

import (
	"github.com/gin-gonic/gin"
	swaggerFiles "github.com/swaggo/files"
	"github.com/swaggo/gin-swagger"
	"net/http"

	_ "use_swagger/docs"
)

// @title API document title
// @version version(1.0)
// @description Description of specifications
// @Precautions when using termsOfService specifications

// @contact.name API supporter
// @contact.url http://www.swagger.io/support
// @contact.email [email protected]

// @license.name license(Mandatory)
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html

// @host localhost:8080
// @BasePath /
func main() {
	r := gin.New()

	url := ginSwagger.URL("http://localhost:8080/swagger/doc.json")
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, url))
	
	r.GET("/test", test)
	r.Run()
}

// @description API details for testing
// @version 1.0
// @accept application/x-json-stream
// @param none query string false "Not required."
// @Success 200 {object} gin.H {"code":200,"msg":"ok"}
// @router /test/ [get]
func test(c *gin.Context){
	c.JSON(http.StatusOK, gin.H{ "msg": "ok"})
}

Initialize the specifications.

$ swag init

After the initialization is completed, the directory structure is as follows.

|-- use_swagger
|-- |-- docs
|-- |-- |-- docs.go
|-- |-- |-- swagger.json
|-- |-- |-- swagger.yaml
|-- |-- main.go
|-- |-- go.mod

Start the server and access http: //localhost:8080/swagger/index.html to display the specifications. キャプチャ.PNG I will actually use it, pass parameters appropriately and execute it. キャプチャ.PNG I got the expected response. キャプチャ.PNG

Commonly used options

API options

option Explanation
description Detailed description of the operation.
id A unique string used to identify the operation. Must be unique among all API operations.(I don't see much where it is used)
tags Shows a list of tags for each API operation, separated by commas, and API relevance.
summary A brief summary of what the operation is doing.
accept API can be usedMIME header typeListof.valueis,MIMEheadertypeMust be as described in.
produce A list of MIME types that the API can generate. value is,MIME header typeMust be as described in.
param Space-separated parameters. Parameter name, parameter type, data type, required? , Comment attribute (optional)
security Security of each API operation.
success Space-separated success response. Response code,{param type}, Data type, comment
failure Space-separated fault response. Response code,{param type}, Data type, comment
router path,[httpMethod]

Usage legend

// @Summary Auth admin
// @Description get admin info
// @Tags accounts,admin
// @Accept  application/x-json-stream
// @Produce  application/x-json-stream
// @Success 200 {object} model.Admin
// @Failure 400 {object} httputil.HTTPError
// @Failure 401 {object} httputil.HTTPError
// @Failure 404 {object} httputil.HTTPError
// @Failure 500 {object} httputil.HTTPError
// @Security ApiKeyAuth
// @Router /admin/auth [post]
func (c *Controller) Auth(ctx *gin.Context) {
	authHeader := ctx.GetHeader("Authorization")
	if len(authHeader) == 0 {
		httputil.NewError(ctx, http.StatusBadRequest, errors.New("please set Header Authorization"))
		return
	}
	if authHeader != "admin" {
		httputil.NewError(ctx, http.StatusUnauthorized, fmt.Errorf("this user isn't authorized to operation key=%s expected=admin", authHeader))
		return
	}
	admin := model.Admin{
		ID:   1,
		Name: "admin",
	}
	ctx.JSON(http.StatusOK, admin)
}
// ShowBottle godoc
// @Summary Show a bottle
// @Description get string by ID
// @ID get-string-by-int
// @Tags bottles
// @Accept  json
// @Produce  json
// @Param  id path int true "Bottle ID"
// @Success 200 {object} model.Bottle
// @Failure 400 {object} httputil.HTTPError
// @Failure 404 {object} httputil.HTTPError
// @Failure 500 {object} httputil.HTTPError
// @Router /bottles/{id} [get]
func (c *Controller) ShowBottle(ctx *gin.Context) {
	id := ctx.Param("id")
	bid, err := strconv.Atoi(id)
	if err != nil {
		httputil.NewError(ctx, http.StatusBadRequest, err)
		return
	}
	bottle, err := model.BottleOne(bid)
	if err != nil {
		httputil.NewError(ctx, http.StatusNotFound, err)
		return
	}
	ctx.JSON(http.StatusOK, bottle)
}

Other API information is Official documentation and [This repository](https://github.com/swaggo/swag/tree/ Please refer to master / example / celler / controller).

Impressions of use

The gin-swagger library isn't very useful, because it's an API spec generated from comments. I think you should check carefully if there are any mistakes when writing. : point_up_tone1:

Recommended Posts

Generate API spec using GO / Gin gin-swagger
Try using Dropbox API v2 with Go
Challenge to generate Yahoo! News headlines using only COTOHA API
[Go language] Collect and save Vtuber images using Twitter API