LoginSignup
29
30

More than 3 years have passed since last update.

GO/Gin gin-swagger使用してAPI仕様書を生成します

Posted at

前書

この記事は gin-swaggerライブラリ使用してGinプロダクトにAPI仕様書生成するための知見をまとめるものになります。
gin-swaggerリポジトリリンク
swagger-banner.png

テスト用のプロダクトを作成

フォルダを作成

// 任意のディレクトリで
$ mkdir use_swagger && cd use_swagger

go modを初期化

$ go mod init use_swagger

ライブラリインストール

$ 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

インストール完了後のバージョン確認。

$ swag -v
swag version v1.6.7

現在のディレクトリ構成

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

プロダクトにAPI仕様書追加

use_swaggerディレクトリ配下にmain.goファイル作成

$ touch main.go

追加前

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"})
}

サーバー立ち上げ後 http://localhost:8080/testにアクセスすると、簡単なJsonデータが戻ってきます。
キャプチャ.PNG

追加後

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ドキュメントのタイトル
// @version バージョン(1.0)
// @description 仕様書に関する内容説明
// @termsOfService 仕様書使用する際の注意事項

// @contact.name APIサポーター
// @contact.url http://www.swagger.io/support
// @contact.email support@swagger.io

// @license.name ライセンス(必須)
// @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の詳細
// @version 1.0
// @accept application/x-json-stream
// @param none query string false "必須ではありません。"
// @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"})
}

仕様書を初期化します。

$ swag init

初期化完了後、ディレクトリ構成は以下のようになりました。

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

サーバーを立ち上げ、http://localhost:8080/swagger/index.htmlへアクセスすれば、仕様書が表示されます。
キャプチャ.PNG
実際使ってみます、適当にパラメータを渡して、実行します。
キャプチャ.PNG
期待通りのレスポンスが返ってきました。
キャプチャ.PNG

よく使用されるオプション

API オプション

オプション 説明
description 操作動作の詳細な説明。
id 操作を識別するために使用される一意の文字列。すべてのAPI操作の中で一意である必要があります。(使用されてる所あんまり見ない)
tags コンマで区切られた各API操作へのタグのリスト、APIの関連性を示します。
summary 操作の実行内容の簡単な要約。
accept APIが使用できるMIMEヘッダタイプのリスト。値は、MIMEヘッダタイプで説明されているとおりでなければなりません。
produce APIが生成できるMIMEタイプのリスト。値は、MIMEヘッダタイプで説明されているとおりでなければなりません。
param スペースで区切られたパラメーター。パラメータ名、パラメータタイプ、データタイプ、必須ですか?、コメント属性(オプション)
security 各API操作のセキュリティ。
success スペースで区切られた成功レスポンス。レスポンスコード、{param type}、データ型、コメント
failure スペースで区切られた障害レスポンス。レスポンスコード、{param type}、データ型、コメント
router パス、[httpMethod]

使用凡例

// @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)
}

その他API情報は公式ドキュメントこちらのリポジトリを参考にしてください。

使用感想

gin-swaggerライブラリは非常に便利とは言えない、コメントから生成されるAPI仕様書であるために、
記述する際には間違えがないかよく確認したほうがいいと思います。:point_up_tone1:

29
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
30