クイック エンジニアリングブログ

株式会社クイック Web事業企画開発本部のエンジニアリングチームが運営する技術ブログです。

SwaggerではじめるOpenAPI開発

こんにちは、ソフトウェアエンジニアのやぎーです。

今回はREST API開発のフレームワーク「Swagger」についてお話ししたいと思います。

こんな人におすすめ

  • RESTful APIをつくりたい
  • Swaggerって聞いたことあるけど触ったことがない
  • APIのドキュメント管理が大変
  • 簡単にモック環境を用意したい

Swaggerとは

まず、SwaggerはRESTfulAPIを構築するためのOpenAPIの仕様に基づいて構築されたオープンソースツールです。 主要な言語のAPIクライアントやモックサーバ、ドキュメントの自動生成などがおこなえます。

RESTful APIを構築するにあたってOpenAPIの記法に沿って定義しておくと、Swaggerを使ってドキュメントの作成・モックサーバーとの連携・コードの自動生成などが行える便利なツールになります。

環境構築

実際に触らないとなかなかイメージ出来ない人もいるかと思いますので、 今回はDocker上で下記の環境を作っていきます。

前提

Docker・Docker Composeの環境構築済み

使用するツール

ツール 概要
Swagger Editor OpenAPIのエディタ・ビューアが一緒になっているツール。画面上で編集した内容がリアルタイムで反映され、構文や仕様のチェックができます。
Swagger UI OpenAPIの定義ファイルをもとに、HTML形式で整形・表示が行える。エンドポイントや、パラメータ・レスポンス定義などが確認でき、設定してあるサーバーに対してリクエストの送信などもできる便利ツールです。
Stoplight Prism OpenAPI定義を渡すだけでモックが作れます。Swagger UIからこのモックに対してリクエストの送信が行えます。

用意するもの

docker-compose.yml

version: '3'

services:
  swagger-editor:
    image: swaggerapi/swagger-editor
    container_name: "swagger-editor"
    volumes:
      - ./openapi.yaml:/openapi.yaml
    environment:
      SWAGGER_FILE: /openapi.yaml
    ports:
      - "8001:8080"

  swagger-ui:
    image: swaggerapi/swagger-ui
    container_name: "swagger-ui"
    ports:
      - "8002:8080"
    volumes:
      - ./openapi.yaml:/openapi.yaml
    environment:
      SWAGGER_JSON: /openapi.yaml

  swagger-mock:
    image: stoplight/prism:3
    container_name: "swagger-api"
    ports:
      - "8003:4010"
    command: mock -h 0.0.0.0 /openapi.yaml
    volumes:
      - ./openapi.yaml:/openapi.yaml

openapi.yaml(サンプル)

下記は/petsに対する一覧取得/作成/ID検索の定義になります。
※書き方に関してはOpenAPI Specificationを参照

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  license:
    name: MIT
servers:
  - url: http://localhost:8003
paths:
  /pets:
    # 一覧取得
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            maximum: 100
            format: int32
      responses:
        '200':
          description: A paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    # 作成
    post:
      summary: Create a pet
      operationId: createPets
      tags:
        - pets
      responses:
        '201':
          description: Null response
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /pets/{petId}:
    # ID検索
    get:
      summary: Info for a specific pet
      operationId: showPetById
      tags:
        - pets
      parameters:
        - name: petId
          in: path
          required: true
          description: The id of the pet to retrieve
          schema:
            type: string
      responses:
        '200':
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pet"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  schemas:
    Pet:
      type: object
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        tag:
          type: string
    Pets:
      type: array
      maxItems: 100
      items:
        $ref: "#/components/schemas/Pet"
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string

上記2ファイルを設置してDockerコンテナを起動します。

docker-compose up -d

起動した画面

Swagger Editor

左のエディタでAPIの定義を変更すると、右側のビューアにリアルタイムで反映されます

Swagger UI

画像は一部分の切り出しになりますが、openapi.yamlに記述した内容が仕様として成形して見ることができます。

モックサーバーからの返却値を指定したい場合には「example」を定義することができます。

Pet:
  type: object
  required:
    - id
    - name
  properties:
    id:
      type: integer
      format: int64
    name:
      type: string
    tag:
      type: string
  # ここに定義
  example:
    id: 1000
    name: "Beagle"
    tag: "Dog"

右上の「Try it out」のボタンから、モックサーバーに対してリクエストを送信するとexampleに定義した値が返却されます。

コードの自動生成

Swagger CodegenOpenAPI Generatorを使用することで、サーバーサイド・クライアントサイドのコードの自動生成にも対応しています。

自動生成されたコードに沿ってビジネスロジックの実装を行うだけなので、実装工数の削減や実装方法の共通化を行うことができます。

まとめ

Swaggerの開発環境構築について紹介をさせていただきました。
まとめとして導入にあたっての注意点やメリットを紹介します。

注意点

  • OpenAPIの知見がない場合の学習コストがそれなりにかかる
  • 既存のAPIを移行する場合にリソース指向アーキテクチャに準拠できていないとOpenAPIでは表現できないことがある

メリット

  • API定義がコードと一緒にGit管理できる
  • Swagger UIを使えば仕様が明確になり共有もしやすい
  • コード自動生成に対応していれば、実装工数削減やサーバー・クライアント間での一貫性を担保しやすい

これからAPI開発を行う方にはメリットも非常に大きいと思いますので、導入候補として検討いただければと思います。

最後までお読みいただきありがとうございました。


\\『真のユーザーファーストでマーケットを創造する』仲間を募集中です!! //

919.jp