0
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でOpenAPIファイルからAPIコードを自動生成する方法〜oapi-codegenの使い方〜

Posted at

はじめに

Go言語でAPIを構築する際に、手動でコードを書くのは手間がかかるだけでなく、エラーが発生しやすくなります。そこで、OpenAPI仕様を活用し、自動でコードを生成する方法を解説します。本記事では、oapi-codegenを使用して、Goコードを自動生成する手順を丁寧に説明します。

oapi-codegenとは?

oapi-codegenは、OpenAPI 3.0仕様に基づいてGoコードを自動生成するツールです。以下のような機能をサポートしています:

  • APIモデルの生成
  • Ginベースのサーバーコード生成
  • クライアントコードの生成
  • OpenAPI仕様を埋め込むコード生成

前提条件

  • Goがインストールされている
  • oapi-codegenのインストール済み

以下のコマンドでoapi-codegenをインストールできます:

go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest

以下のコマンドでバージョンが出力されるか確認する

$ oapi-codegen -version

もし、

zsh: command not found: oapi-codegen

になった場合は、パスを通す。

go-api-newspaper % go env | grep PATH
# => GOPATH='/Users/jima/go'

go-api-newspaper %ls /Users/jima/go/bin      
# => gopls           oapi-codegen    staticcheck

go-api-newspaper % export PATH=$PATH:/Users/jima/go/bin
go-api-newspaper % echo 'export PATH=$PATH:/Users/jima/go/bin' >> ~/.zshrc
go-api-newspaper % source ~/.zshrc
go-api-newspaper % oapi-codegen -version
# => github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen
# => v2.4.1

OpenAPI仕様のYAMLファイルを作成する

以下は、本記事で使用するサンプルのOpenAPI仕様です。このファイルをopenapi.yamlとして保存してください。

openapi.yaml
openapi: 3.0.3
info:
  title: Go API Template # APIの名称。新聞管理用のテンプレートを定義。
  version: 1.0.0         # APIのバージョン。メジャー、マイナー、パッチ番号で管理。
servers:
  - url: http://0.0.0.0:8080/api/v1  # Dockerや他の環境でAPIをテストする際のベースURL。
  - url: http://localhost:8080/api/v1 # ローカルホストでの開発時に使用。
  - url: http://127.0.0.1:8080/api/v1 # ループバックアドレスを使用する場合のURL。
paths:
  /newspaper:
    post:
      summary: Create a new newspaper # 新聞記事を新規作成するエンドポイント。
      operationId: createNewspaper    # 操作を一意に識別するID。
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewspaperCreateRequest' # 新規作成に必要なデータの構造を参照。
        required: true # リクエストボディが必須であることを指定。
      responses:
        '201':
          description: Created # リソースが正常に作成された場合のレスポンス。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NewspaperResponse' # 作成された新聞データのレスポンス構造。
        '400':
          description: Bad Request # 入力データが不正だった場合のレスポンス。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse' # エラー情報の構造を参照。
  /newspaper/{id}:
    get:
      summary: Find newspaper by ID # IDで新聞記事を取得するエンドポイント。
      operationId: getNewspaperById
      parameters:
        - name: id
          in: path
          required: true # パスパラメータが必須であることを指定。
          schema:
            type: integer # IDは整数型。
      responses:
        '200':
          description: OK # 正常にデータが取得された場合。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NewspaperResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found # 指定されたIDの新聞記事が見つからない場合。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      summary: Update a newspaper by ID # IDで新聞記事を更新するエンドポイント。
      operationId: updateNewspaperById
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewspaperUpdateRequest' # 更新データの構造を参照。
        required: true
      responses:
        '200':
          description: Updated # 更新成功時のレスポンス。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NewspaperResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      summary: Delete a newspaper by ID # IDで新聞記事を削除するエンドポイント。
      operationId: deleteNewspaperById
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: No Content # 成功した場合、コンテンツなしのレスポンスを返す。
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    NewspaperResponse:
      type: object
      properties:
        id:
          type: integer # 新聞記事の一意の識別子。
        title:
          type: string  # 新聞記事のタイトル。
        columnName:
          type: string  # コラム名を指定。
      required:
        - id
        - title
        - columnName
    NewspaperUpdateRequest:
      type: object
      properties:
        title:
          type: string  # 更新対象のタイトル。
        columnName:
          type: string  # 更新対象のコラム名。
    NewspaperCreateRequest:
      type: object
      properties:
        title:
          type: string  # 作成時に必要な新聞記事のタイトル。
        columnName:
          type: string  # 作成時に必要なコラム名。
      required:
        - title
        - columnName
    ErrorResponse:
      type: object
      properties:
        message:
          type: string  # エラーに関する詳細な説明を含む文字列。
      required:
        - message # エラーメッセージは必須プロパティ。

oapi-codegenでコードを生成する

oapi-codegenの設定を記載したconfig.yamlを作成します:

config.yaml
package: api           # 生成されるコードのパッケージ名
generate:
  models: true         # モデルコードの生成
  gin-server: true     # Gin用サーバーコードの生成
  client: true         # クライアントコードの生成
  embedded-spec: true  # OpenAPI仕様を埋め込む
output: api/api.gen.go # 生成されるコードの出力先

そして、以下のコマンドを実行します。

oapi-codegen --config=./config.yaml ./openapi.yaml

このコマンドを実行すると、api.gen.goというファイルが自動生成されます。

生成されたコードの確認

api.gen.goには、以下のようなコードが生成されます:

  • リクエスト/レスポンス用のモデル
  • Ginベースのエンドポイントハンドラ
  • クライアントコード

まとめ

本記事では、oapi-codegenを使用して、GoのAPIコードを効率的に生成する方法を解説しました。コード生成により、開発スピードの向上やバグの削減が期待できます。ぜひ、実際のプロジェクトで活用してみてください!

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