1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Go Echo】Swaggerチュートリアル

Posted at

【Go Echo】Swaggerチュートリアル

このチュートリアルでは、GoのEchoフレームワークを使用してCRUD APIサーバーを構築し、Swaggerを用いてAPIドキュメントを生成する手順を説明します。
また、Swaggerアノテーションの詳細な解説も後半で行います。

前提条件

  • Goがインストールされていること
  • 基本的なGoの知識があること

1. プロジェクトのセットアップ

まず、プロジェクト用のディレクトリを作成し、初期化します。

mkdir echo-swagger-crud
cd echo-swagger-crud
go mod init github.com/yourusername/echo-swagger-crud

2. 必要なパッケージのインストール

EchoフレームワークとSwaggerツールをインストールします。

go get github.com/labstack/echo/v4
go get github.com/swaggo/echo-swagger
go get github.com/swaggo/swag/cmd/swag
go mod tidy

swagコマンドをパスに追加します(必要に応じて)。

echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.zshrc
source ~/.zshrc

3. CRUD APIの実装

main.goファイルを作成し、基本的なCRUDエンドポイントを実装します。

package main

import (
    "net/http"

    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
    echoSwagger "github.com/swaggo/echo-swagger"
    _ "github.com/yourusername/echo-swagger-crud/docs"
)

// @title Echo CRUD API
// @version 1.0
// @description サンプルのCRUD APIです。
// @host localhost:8080
// @BasePath /api/v1
func main() {
    e := echo.New()

    // ミドルウェア
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    // ルート
    e.GET("/swagger/*", echoSwagger.WrapHandler)

    // APIグループ
    api := e.Group("/api/v1")
    {
        api.GET("/items", getItems)
        api.GET("/items/:id", getItem)
        api.POST("/items", createItem)
        api.PUT("/items/:id", updateItem)
        api.DELETE("/items/:id", deleteItem)
    }

    e.Start(":8080")
}

// Item represents a simple item
type Item struct {
    ID    string `json:"id"`
    Name  string `json:"name"`
    Price int    `json:"price"`
}

// 仮のデータ
var items = map[string]Item{}

// @Summary Get all items
// @Tags items
// @Success 200 {array} Item
// @Router /items [get]
func getItems(c echo.Context) error {
    var list []Item
    for _, item := range items {
        list = append(list, item)
    }
    return c.JSON(http.StatusOK, list)
}

// @Summary Get an item by ID
// @Tags items
// @Param id path string true "Item ID"
// @Success 200 {object} Item
// @Failure 404 {string} string "Not Found"
// @Router /items/{id} [get]
func getItem(c echo.Context) error {
    id := c.Param("id")
    item, exists := items[id]
    if !exists {
        return c.String(http.StatusNotFound, "Not Found")
    }
    return c.JSON(http.StatusOK, item)
}

// @Summary Create a new item
// @Tags items
// @Param item body Item true "Item to create"
// @Success 201 {object} Item
// @Router /items [post]
func createItem(c echo.Context) error {
    var item Item
    if err := c.Bind(&item); err != nil {
        return err
    }
    items[item.ID] = item
    return c.JSON(http.StatusCreated, item)
}

// @Summary Update an existing item
// @Tags items
// @Param id path string true "Item ID"
// @Param item body Item true "Updated item"
// @Success 200 {object} Item
// @Failure 404 {string} string "Not Found"
// @Router /items/{id} [put]
func updateItem(c echo.Context) error {
    id := c.Param("id")
    if _, exists := items[id]; !exists {
        return c.String(http.StatusNotFound, "Not Found")
    }
    var item Item
    if err := c.Bind(&item); err != nil {
        return err
    }
    items[id] = item
    return c.JSON(http.StatusOK, item)
}

// @Summary Delete an item
// @Tags items
// @Param id path string true "Item ID"
// @Success 204 {string} string "No Content"
// @Failure 404 {string} string "Not Found"
// @Router /items/{id} [delete]
func deleteItem(c echo.Context) error {
    id := c.Param("id")
    if _, exists := items[id]; !exists {
        return c.String(http.StatusNotFound, "Not Found")
    }
    delete(items, id)
    return c.NoContent(http.StatusNoContent)
}

4. Swaggerドキュメントの生成

swagを使用してSwaggerドキュメントを生成します。

swag init

これにより、docsディレクトリが作成され、Swaggerドキュメントが生成されます。

5. サーバーの起動

以下のコマンドでサーバーを起動します。

go run main.go

6. Swagger UIの確認

ブラウザで http://localhost:8080/swagger/index.html にアクセスすると、Swagger UIが表示され、APIのドキュメントを確認できます。

7. アノテーションの解説

Swaggerアノテーションを使用してAPIドキュメントを生成するために、コード内に特定のコメントを追加します。
以下では、主なアノテーションについて解説します。

7.1 主なアノテーション一覧

1. API全体の設定

ファイルやパッケージの先頭にAPI全体の情報を記述します。
これにより、Swaggerドキュメントの基本情報が設定されます。

// @title Echo CRUD API
// @version 1.0
// @description サンプルのCRUD APIです。
// @host localhost:8080
// @BasePath /api/v1
  • @title: APIのタイトル
  • @version: バージョン番号
  • @description: APIの説明
  • @host: APIのホスト名
  • @BasePath: ベースとなるパス

2. ハンドラー関数のアノテーション

各APIエンドポイントに対応するハンドラー関数にアノテーションを追加します。
これにより、エンドポイントごとの詳細なドキュメントが生成されます。

基本構造
// @Summary 簡単な説明
// @Description 詳細な説明
// @Tags タグ名
// @Accept リクエストのコンテンツタイプ
// @Produce レスポンスのコンテンツタイプ
// @Param パラメータ名 パラメータの場所 型 必須 "説明"
// @Success ステータスコード {型} モデル "説明"
// @Failure ステータスコード {型} モデル "説明"
// @Router パス [メソッド]
func ハンドラー関数名(c echo.Context) error {
    // 実装
}
具体例
// @Summary 全てのアイテムを取得
// @Description データベースから全てのアイテムを取得します。
// @Tags items
// @Accept json
// @Produce json
// @Success 200 {array} Item
// @Router /items [get]
func getItems(c echo.Context) error {
    // 実装
}
  • @Summary: エンドポイントの概要
  • @Description: エンドポイントの詳細説明
  • @Tags: エンドポイントの分類タグ
  • @Accept: リクエストのコンテンツタイプ(例: json)
  • @Produce: レスポンスのコンテンツタイプ(例: json)
  • @Param: パラメータの定義
    • {パラメータ名}: パラメータの名前
    • {場所}: パラメータの場所(path, query, bodyなど)
    • {型}: パラメータのデータ型
    • {必須}: パラメータが必須かどうか(true/false)
    • "{説明}": パラメータの説明
  • @Success: 成功時のレスポンス定義
    • {ステータスコード}: HTTPステータスコード
    • {型}: レスポンスのデータ型
    • {モデル}: レスポンスで使用するモデル
    • "{説明}": レスポンスの説明
  • @Failure: 失敗時のレスポンス定義
  • @Router: エンドポイントのパスとHTTPメソッド

3. パラメータの定義

パラメータは@Paramアノテーションを使用して定義します。

// @Param id path string true "アイテムID"
  • id: パラメータ名
  • path: パラメータの場所(path, query, header, body)
  • string: パラメータの型
  • true: 必須であることを示す
  • "アイテムID": パラメータの説明

構文:

@Param {name} {in} {type} {required} "{description}"

例:

パスパラメータとしてidを必須とする場合

// @Param id path string true "アイテムID"

4. レスポンスの定義

成功時や失敗時のレスポンスは@Success@Failureで定義します。

// @Success 200 {object} Item "成功時の説明"
// @Failure 404 {object} HTTPError "見つからない場合の説明"
  • @Success: 成功時のレスポンス
  • @Failure: 失敗時のレスポンス

構文:

@Success {status_code} {type} {model} "{description}"

例:

// @Success 201 {object} Item "アイテム作成成功"
// @Failure 400 {object} HTTPError "不正なリクエスト"

5. モデル(構造体)のアノテーション

APIで使用するデータモデルにもアノテーションを追加できます。これにより、Swagger UIでモデルの詳細が表示されます。

// Item represents a single item in the store
// @Description ストア内のアイテムの構造体
type Item struct {
    // @Description アイテムの一意な識別子
    ID    string `json:"id" example:"1"`
    // @Description アイテムの名前
    Name  string `json:"name" example:"Sample Item"`
    // @Description アイテムの価格(セント単位)
    Price int    `json:"price" example:"1000"`
}
  • @Description: 構造体やフィールドの説明
  • example: 各フィールドの例示値

7.2 モデルの詳細説明

モデル(構造体)にアノテーションを追加することで、Swagger UI上でモデルの詳細な説明や例示値を表示できます。
これにより、APIを利用する開発者に対して、データ構造の理解を深めてもらうことが可能です。

例:

// Item represents a single item in the store
// @Description ストア内のアイテムの構造体
type Item struct {
    // @Description アイテムの一意な識別子
    ID    string `json:"id" example:"1"`
    // @Description アイテムの名前
    Name  string `json:"name" example:"Sample Item"`
    // @Description アイテムの価格(セント単位)
    Price int    `json:"price" example:"1000"`
}
  • 各フィールドに@Descriptionを追加することで、フィールドの役割や意味を明確に伝えることができます。
  • exampleタグを使用して、各フィールドの具体的な例を示すことができます。これにより、API利用者が期待されるデータ形式や値を理解しやすくなります。

8. まとめ

以上で、GoのEchoフレームワークを使用したCRUD APIサーバーにSwaggerを実装する基本的な手順は完了です。
アノテーションを活用することで、APIの設計とドキュメント化が容易になり、開発効率が向上します。
Swagger UIを利用することで、APIの仕様を視覚的に確認・共有できるため、チーム開発においても非常に有用です。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?