OpenAPI の定義フォーマット

プログラミング

OAS【OpenAPI Specification】とは OpenAPI Initiative が提唱する RESTful API の定義フォーマットです。
フォーマットに則って定義することで、あなたのプログラムは洗練され、自動ドキュメント化などのツールを利用することができるようになります。

参考: OpenAPI による RESTful API 開発のすすめ

API の定義は OAS によって定められたフォーマットで記述します。
JSON 形式と YAML 形式の2種類があり、文字コードは UTF-8 です。
ここでは YAML 形式のフォーマットにて解説いたします。

以下は YAML 形式で記述された API 定義のおおまかな概要です。

openapi: 3.1.0
info:
  /* メタ情報 */

servers:
  /* サーバ情報 */

tags:
  /* タグ情報 */

paths:
  /* パス情報 */

components:
  /* コンポーネント情報 */

ここでは以下のサンプル定義を元に、各 Schema の内容について説明します。

サンプル API 定義ファイル(右クリックでダウンロードしてください)
Redocly にて作成された API ドキュメント

詳細は正式なドキュメントを参照してください。

OpenAPI Specification v3.1.0 – 4.8 Schema
https://spec.openapis.org/oas/v3.1.0#schema


バージョンとメタ情報(OpenAPI Object, Info Object)
[OpenAPI Object, Info Object]
まずはじめに OpenAPI のバージョンと、当該 API のメタ情報を記述します。

openapi: 3.1.0 # 必須:使用するOpenAPIのバージョン

info:
  title: Swagger Petstore # タイトル(必須)
  version: 1.0.1 # 当該APIのバージョン(必須)
  description: |
    これはテスト用の Petstore server です。

    # Introduction
    This API is documented in **OpenAPI format** and is based on
    [Petstore sample](http://petstore.swagger.io/) provided by [swagger.io](http://swagger.io) team.

  contact: # コンタクト情報
    name: API Support
    email: apiteam@swagger.io
    url: https://github.com/Redocly/redoc

  license: # ライセンス情報
    name: Apache 2.0
    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'

この部分は、Redocly 等のドキュメントツールで出力した API ドキュメント上で以下のように表示されます。

APIドキュメント - メタ情報

description内で#を定義することで画像のように見出しとして出力され、左メニューにも表示されます。


サーバ情報(Server Object)
[Server Object]
次に API サーバの情報を記述します。
複数の指定が可能で右メニューで URL を確認できるようになります。

APIドキュメント - サーバ情報
servers:
  - url: https://petstore.swagger.io/v2 # サーバURL(必須)
    description: Default server # 説明
  - url: https://petstore.swagger.io/sandbox
    description: Sandbox server


タグ情報(Tag Object)
[Tag Object]
各エンドポイントを意味のある機能単位にタグ付けしてグルーピングすることにより、メニューからエンドポイントを探しやすくなります。
タグの一覧は API ドキュメントの左メニューに表示されます。
さらに拡張プロパティx-tagGroupsを利用することで、タグのグルーピングも行えます。

APIドキュメント - タグ情報
tags:
  - name: pet # タグ名(必須)
    description: Everything about your Pets # 説明
  - name: store
    description: Access to Petstore orders
  - name: user
    description: Operations about user
x-tagGroups:
  - name: General
    tags:
      - pet
      - store
  - name: User Management
    tags:
      - user


パス情報(Paths Object, Path Item Object)
[Paths Object, Path Item Object]
各エンドポイントの定義です。
パスとそのパスに対するリクエストの種別を記述します。
以下はその概要です(オペレーション情報の内容については後述します)。

paths:
  /user: # リクエストURI
    get: # リクエスト種別 get|put|post|delete|etc..
      /* オペレーション情報 */
    post:
      /* オペレーション情報 */

  '/user/{username}': # リクエストパラメタ
    delete:
      /* オペレーション情報 */
    get:
      /* オペレーション情報 */


コンポーネント情報(Components Object)
[Components Object]
再利用可能なオブジェクトはcomponentsに記述します。
以下はその概要です(個々の内容については後述します)。

components:
  schemas:
    /* 入出力データの型情報 */

  securitySchemes:
    /* セキュリティ情報 */

  examples:
    /* サンプルの型情報 */


オペレーション情報(Operation Object)
[Operation Object]
各パスに対するリクエストやレスポンスの定義です。
いくつか例を挙げて説明します。


パラメタなしの場合
リクエストもレスポンスもパラメタのない最もシンプルな定義の記述例です。

APIドキュメント - パラメタなし
paths:
  /user:
    get:
      tags:
        - user
      summary: ユーザー管理の権限チェック # タイトル
      description: 'ユーザー管理が使用可能かチェックします。' # 説明
      operationId: checkUser # ユニークな識別子


リクエストとレスポンスにパラメタが存在する場合(Parameter Object)
[Parameter Object]
GET パラメタを指定する場合の記述例です。
レスポンスは204400404が返ってきます。

APIドキュメント - パラメタあり
paths:
  '/user/{username}':
    delete:
      tags:
        - user
      summary: 利用者の削除
      description: 利用者を削除します。
      operationId: deleteUser
      parameters:
        - name: username # パラメタ名(必須)
          in: path # query|header|path|cookie パラメタの場所(必須)
          description: 削除する利用者名 # 説明
          required: true # 必須かどうか
          schema:
            type: string # string|integer|number データタイプ(必須)
      responses:
        '204':
          description: 利用者を削除しました。
        '400':
          description: 利用者の指定に誤りがあります。
        '404':
          description: 指定された利用者は存在しません。


リクエストパラメタがヘッダや cookie の場合(Parameter Object)
[Parameter Object]
HTTP ヘッダや cookie にパラメタを設定する場合の記述例です。

APIドキュメント - ヘッダやcookieあり
paths:
  /pet:
    post:
      parameters:
        - name: Accept-Language # パラメタ名(必須)
          in: header # query|header|path|cookie パラメタの場所(必須)
          description: 許可する言語 # 説明
          required: false # 必須かどうか
          example: en-US
          schema:
            type: string
            default: en-AU
        - name: cookieParam
          in: cookie
          description: クッキーパラメータ
          required: true
          schema:
            type: integer
            format: int64
・・・


リクエストボディが存在する場合(Request Body Object, Reference Object)
[Request Body Object, Reference Object]
以下は JSON 形式のリクエストボディがある場合の記述例です。

APIドキュメント - リクエストボディあり
paths:
  /user:
    post:

・・・

      requestBody: # リクエストボディ
        description: 作成する利用者情報
        required: true
        content: # リクエストボディの内容(必須)
          application/json:
            schema:
              type: object
              properties:
                username:
                  description: 氏名
                  type: string
                  minLength: 4
                  example: John78
                email:
                  description: メールアドレス
                  type: string
                  format: email
                  example: john.smith@example.com
                password:
                  description: >-
                    ログインパスワード、8文字以上の英数字
                  type: string
                  format: password
                  minLength: 8
                  pattern: '/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])/'
                  example: drowssaP123
                userStatus:
                  description: 利用者のステータス
                  type: integer
                  format: int32


再利用されるschemacomponentsに定義し、$refで参照するように定義することも可能です。

paths:
  /user:
    post:

・・・

     requestBody:
        content:
          application/json:
            schema:
               $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        username:
          description: 氏名
          type: string
          minLength: 4
          example: John78
        email:
          description: メールアドレス
          type: string
          format: email
          example: john.smith@example.com
        password:
          description: >-
            ログインパスワード、8文字以上の英数字
          type: string
          format: password
          minLength: 8
          pattern: '/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])/'
          example: drowssaP123
        userStatus:
          description: 利用者のステータス
          type: integer
          format: int32


レスポンスボディが存在する場合(Responses Object)
[Responses Object]
レスポンスボディの内容は前項でcomponetsに定義したものを$refで参照しています。

APIドキュメント - レスポンスボディあり
paths:
  '/user/{username}':
    get:

・・・

      responses:
        '200':
          description: 利用者情報を取得しました。
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
            application/xml:
              schema:
                $ref: '#/components/schemas/User'
        '400':
          description: 利用者の指定に誤りがあります。
        '404':
          description: 指定された利用者は存在しません。


認証が必要な場合(Security Requirement Object, Security Schema Object)
[Security Requirement Object, Security Shema Object]
API KEY などのセキュリティ情報による認証が必要な場合に記述します。

APIドキュメント - セキュリティ情報あり
paths:
  '/pet/{petId}':
    get:

・・・

      security:
        - api_key: []
components
  securitySchemes:
    api_key:
      type: apiKey # apiKey|http|mutualTLS|oauth2|openIdConnect 種別(必須)
      description: >
        API キーを設定して認証します。
      name: api_key # セキュリティ名(必須)
      in: header # query|header|path|cookie API KEYの場所(必須)


サンプルコードが存在する場合(Specification Extentions)
[Specification Extentions]

APIドキュメント - サンプルコードあり
paths:
  /pet:
    post:

・・・

      x-codeSamples:
        - lang: 'C#'
          source: |
            PetStore.v1.Pet pet = new PetStore.v1.Pet();
            pet.setApiKey("your api key");
            pet.petType = PetStore.v1.Pet.TYPE_DOG;
            pet.name = "Rex";
            // set other fields
            PetStoreResponse response = pet.create();
            if (response.statusCode == HttpStatusCode.Created)
            {
              // Successfully created
            }
            else
            {
              // Something wrong -- check response for errors
              Console.WriteLine(response.getRawResponse());
            }
        - lang: PHP
          source: |
            $form = new \PetStore\Entities\Pet();
            $form->setPetType("Dog");
            $form->setName("Rex");
            // set other fields
            try {
                $pet = $client->pets()->create($form);
            } catch (UnprocessableEntityException $e) {
                var_dump($e->getErrors());
            }

コメント