朝日ネット 技術者ブログ

朝日ネットのエンジニアによるリレーブログ。今、自分が一番気になるテーマで書きます。

OpenAPI Specification 3.0 チートシート

はじめに

こんにちは。朝日ネットでWebアプリケーションの開発を行っている tommy です。

OpenAPI Specification は RESTful な API を記述するための仕様です1。2015年に Open API Initiative が発足し、それまで Swagger という名前で進められていたプロジェクトを引き継ぎました。 現在では実質上の世界標準といえます。

今回は、この OpenAPI を書いている時に、コピペして使える、逆引きの小さなサンプル集が欲しいと思ったので、書いていこうと思います2

OpenAPI について

OpenAPI は yaml 3 で REST の API を記述するための仕様です。
周辺ツール充実していて、仕様に従って REST API を記述しておけば、その内容から見やすいドキュメントを出力してくれたり(Swagger UI)、モックサーバを簡単に作れたりします(Swagger Codepen)。
また、OpenAPI 用のファイルを作成するための Swagger Editor というツールがブラウザで使用でき、これを使えば簡単に yaml を作成できます。
逆に、言語によってはソースコードから OpenAPI のファイルを作成することもできます(Swagger Core など)。

私が特に OpenAPI で書くようにすると良いと思う点は、APIの仕様についての会話を yaml ファイルでできることです。 自然言語 で API のドキュメントを書いておくと、解釈違いやドキュメントの更新漏れなどが頻繁に起こってしまいます。 OpenAPI の仕様に従って API を記述しておけば、そういった事故が起こりづらくなりますし、API を試してみる機能などもあるので、常にそれが動くようにしておけば、実装とドキュメントとの乖離も起こりづらくできます。

Swagger Editor

非常に簡単に、Swagger 及び Open API Specification 3.0 を記述することができるエディタです。このツールが非常に使いやすいのが、個人的に OpenAPI を使うモチベーションになります。 こちら からブラウザ上ですぐに利用することができます4
Ctrl + Space で自動補完が可能であり、これで記述可能なキーを見るだけでさくさくと yaml を書いていくことができます5
また、右枠に現在のコードによるドキュメントがリアルタイムにプレビュー表示されるため逐次確認しながら書いていくことができます。 yaml 中に openapi: 3.0.0 と書いてあるか 、swagger: "2.0" と書いてあるかでエディタの自動補完が変わります。

f:id:a-tommy:20190227143429p:plain

yaml ファイルをもらったら、 Swagger Editor にコピペするだけで、そのAPIをドキュメント化することができ非常に便利です。 また、上のメニューの Generate Server、 Generate Client からいろいろな言語によるモックを出力できます6

チートシート

GET アクセス

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    get:
      responses:
        "200":
          description: ok

必要最低限を書くとこうなります。

パラメータ (parameters)

in でパラメータを渡す場所を指定できます。下記以外にも header (ヘッダ) や cookie (クッキー) が指定できます。

クエリパラメータ
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    get:
      parameters:
        - in: query
          name: userId
          required: false
          schema:
            type: string
      responses:
        "200":
          description: ok
パスパラメータ

required: true が必須なので注意。
また、対応する parameter も必須。

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge/{foo}:
    get:
      parameters:
        - in: path
          name: foo
          required: true
          schema:
            type: string
      responses:
        "200":
          description: ok

リクエスト本文 (requestBody)

PUT や DELETE なども、post の部分を書き換えるだけで作れます。

multipart/form-data
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    post:
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                foo:
                  type: string
                bar:
                  type: integer
                baz: # ファイル
                  type: string
                  format: binary
      responses:
        "200":
          description: ok
JSON リクエスト
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    post:
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                foo:
                  type: string
                bar:
                  type: integer
      responses:
        "200":
          description: ok
XML リクエスト

上記 JSON リクエスト application/json を application/xml にするだけ、なのですがプレビューがうまく動かないので、 後述の コンポーネントを利用して書いています。

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    post:
      requestBody:
        content:
          application/xml:
            schema:
              $ref: "#/components/schemas/piyo" 
      responses:
        "200":
          description: ok
components:
  schemas:
    piyo:
      type: object
      properties:
        foo:
          type: string
        bar:
          type: integer
ファイルアップロード
jpeg ファイルアップロード
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    post:
      requestBody:
        content:
          image/jpeg:
            schema:
              type: string
              format: binary
      responses:
        "200":
          description: ok
画像 ファイルアップロード

サブタイプにアスタリスクも指定できます。

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    post:
      requestBody:
        content:
          image/*:
            schema:
              type: string
              format: binary
      responses:
        "200":
          description: ok

リクエストサンプル

値(value) のサンプル
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    post:
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                foo:
                  type: string
                  example: "foo!"
                bar:
                  type: integer
                  example: 10
      responses:
        "200":
          description: ok
オブジェクトサンプル

結果は上記と同じです。

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    post:
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                foo:
                  type: string
                bar:
                  type: integer
              example:
                foo: "foo!"
                bar: 10
      responses:
        "200":
          description: ok

コンポーネント (components)

コンポーネントは、OpenAPI の yaml 内で同じ構造が何度も出てくる場合に参照して使いまわせる仕組みです。

複数のBodyの形式をサポート (JSON, XML)
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/piyo" 
          application/xml:
            schema:
              $ref: "#/components/schemas/piyo" 
      responses:
        "200":
          description: ok
components:
  schemas:
    piyo:
      type: object
      properties:
        foo:
          type: object
          properties:
            bar:
              type: string

サーバー (servers)

API が動いているサーバーの情報を記述できるほか、Swagger UI から API を試してみるときに使われます。

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
servers:
  - url: https://example.com/api/v1
paths:
  /hoge:
    get:
      responses:
        "200":
          description: ok

配列なので複数書くことができます。

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
servers:
  - url: http://example.com/api/v1
  - url: https://example.com/api/v1
paths:
  /hoge:
    get:
      responses:
        "200":
          description: ok

複数プロトコルが存在する場合などに、variables を使って一つにまとめることができます。

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
servers:
  - url: "{protocol}://test{number}.example.com:{port}/api/v1" 
    variables:
      protocol:
        default: https
        enum:
          - http
          - https
      number:
        default: "1" 
      port:
        default: "443" 
        enum:
          - "443" 
          - "8080" 
paths:
  /hoge:
    get:
      responses:
        "200":
          description: ok

認証 (components/securitySchemes)

認証情報は、components の中の securitySchemes の中に記述します。 それを、認証が必要な要素の security キーから参照します。

クッキーを使った認証も書くことができますが、クッキーとして飛ばすキーと値は固定のものしか記述できず、セッション認証のようなことはできません。

基本認証 (Basic認証)
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    get:
      security:
        - BasicAuth: [] # 配列内は権限のスコープ。OAuth と OpenIDConnect 以外は空配列
      responses:
        "200":
          description: ok
components:
  securitySchemes:
    BasicAuth: # 任意の識別子
      type: http
      scheme: basic
OAuth 認証
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    get:
      security: 
        - OAuth2:
          - read
      responses:
        "200":
          description: ok
    post:
      security: 
        - OAuth2:
          - write
      responses:
        "200":
          description: ok
components:
  securitySchemes:
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://example.com/oauth/authorize
          tokenUrl: https://example.com/oauth/token
          scopes:
            read: "読み取り権限"
            write: "書き込み権限"

APIのテストをするならサーバ側で、テスト用の固定のセッションIDを用意したりする必要があります。

openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    get:
      security: 
        - CookieAuth: []
      responses:
        "200":
          description: ok
components:
  securitySchemes:
    CookieAuth:
      type: apiKey
      in: cookie
      name: SSID

タグ

各APIにタグをつけてグルーピングすることができます。

タグを付ける
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
paths:
  /hoge:
    get:
      tags:
        - hoge
      responses:
        "200":
          description: ok
  /piyo:
    get:
      tags:
        - fuga
      responses:
        "200":
          description: ok
タグについての説明を追加
openapi: 3.0.0
info:
  title: HogeHoge
  version: 1.0.0
tags:
  - name: hoge
    description: hogehoge
    externalDocs:
      description: test
      url: http://example.com/doc
paths:
  /hoge:
    get:
      tags:
        - fuga
      responses:
        "200":
          description: ok
  /piyo:
    get:
      tags:
        - hoge
        - fuga
      responses:
        "200":
          description: ok

おわりに

以上、よく使いそうなパターンを書いてみました。
本記事ではあえて省略しましたが、大抵の場所に summary キーや description キーで説明が書けるので、実用上は適切な説明を書いておくべきです。
Swagger Editor のおかげで簡単に試してみることができるので、書いたことがない人もぜひ OpenAPI で REST の API を定義してみてください。

採用情報

朝日ネットでは新卒採用・キャリア採用を行っております。


  1. カタカナで オープンAPI というと、日本だと一般に公開されたAPIという意味にもなるので注意。

  2. Swagger 2.0 から OpenAPI 3.0 になったことで仕様がだいぶすっきりした上に、公式のドキュメント がわかりやすいため調べながら書くのもそれほど大変なわけではないです。

  3. JSONでも記述可能。

  4. Github からダウンロードして手元で立ち上げることも簡単にできます。

  5. ただし、若干不安定なところがあり、書いてる途中に補完できなくなったり記述した内容が、ページをリロードしないと反映されなかったりします。

  6. Swagger 2.0 か OpenAPI 3.0 かで出力できるコードの言語の種類も変わります。