OpenAPI Specification 3.0.3規約

フューチャー株式会社

本コーディング規約は、世の中のシステム開発プロジェクトのために無償で提供致します。
ただし、掲載内容および利用に際して発生した問題、それに伴う損害については、フューチャー株式会社は一切の責務を負わないものとします。
また、掲載している情報は予告なく変更することがございますので、あらかじめご了承下さい。

1 はじめに

本ドキュメントは OpenAPI Specification 3.0.3に則った API ドキュメントを記述する際のコーディング規約をまとめている。 旧バージョンであるOpenAPI Specification 2.0 の規約も存在するため、v2 を使用している場合はそちらを参照されたい。

2 前提条件

本規約は以下の前提条件に基づいて作成されており、ToC 向けの LSUDs(Large Set of Unknown Developers)向けの Web API には適合しない場合もあるのでご留意いただきたい。

3 免責事項

::: warning 有志で作成したドキュメントである

:::

4 API設計

Web API の設計自体はこの規約の範囲外であるが、簡易的な方針を示す。必要に応じて参考にされたい。

4.1 HTTP メソッド

実現したい操作により、以下のような使い分けを想定する。HEAD(リソースの存在チェック)、GET(参照)、POST(新規作成)、PUT(更新)、PATCH(一部更新)、DELETE(削除)。

4.2 HTTP ステータス

RFC 7231で定義されているレスポンスステータスコードを利用します。

RFC9205日本語訳)の方針に原則則る。ユースケース別に利用すべき HTTP ステータスコードを記載します。

4.2.1 共通

4.2.2 GET

4.2.3 POST

4.2.4 PUT

4.2.5 DELETE

4.3 API バージョン管理

4.4 パラメータの命名

boolean 型である場合、 [a-zA-Z0-9-_]+_flag という命名は非推奨とする。

is_[a-zA-Z0-9-_]+has_[a-zA-Z0-9-_]+ などの命名を代わりに検討する

5 YAMLファイルフォーマット

OpenAPI ドキュメントは JSON 形式、YAML 形式いずれかのフォーマットで記載できるが YAML 形式 を利用する。理由として、JSON と比較して YAML は視覚的に見やすく、レビューや差分管理が行いやすいためである。

5.1 ファイル名

ファイルの拡張子は yaml とする。通常ファイル名は api.yamlswagger.yaml(v2 の場合) を推奨する。

もし、複数の Swagger 定義を管理するため区別したい場合は ${service}_api.yaml とする。

${service} にはサービス名を指定する

5.2 YAML バージョン

YAML v1.2を用いる。

5.3 ファイルレイアウト

5.4 クォート

クォートは可読性を上げるために、できる限り利用しない。利用する場合はダブルクォートを利用する。

# OK
description: 何かしらの説明

# NG(クォートでのラップは不要)
description: '何かしらの説明'
description: "何かしらの説明"

以下の場合は必須で利用する

5.5 YAML 配列スタイル

5.6 改行の表現

改行を含む場合は、パイプ(ブロックスカラー) | を用いる

description: |
  説明文1
  説明文2
     - 箇条書き1
     - 箇条書き2
     - 箇条書き3

6 OpenAPI ドキュメントの構成要素

OpenAPI ドキュメントを構成する要素はオブジェクトと呼ばれ、ルートオブジェクトは以下の要素で構成される。

各種規約を理解する上で、これらの要素を大まかに把握しておくことが重要である。

各オブジェクトの詳細については公式ドキュメントを参照されたい。

フィールド名 必須 説明
openapi OpenAPI ドキュメントが使用する OpenAPI 仕様のバージョン番号
info API に関するメタデータ
servers API サーバへの接続情報
paths API の利用可能なパスと操作方法
components 複数の API における共通の定義
security API 全体で利用可能なセキュリティ(認証)機構
tags 各種 API をグルーピングするためのタグ
externalDocs 追加の外部ドキュメント

続いて各構成要素ごとに具体的なコーディング規約を記載していく。

7 openapi

OpenAPI ドキュメントが使用する OpenAPI 仕様のセマンティックバージョン番号を記載する。

本規約はバージョン3.0.3を対象としているため、3.0.3とする。

良い例:

openapi: 3.0.3

悪い例:

openapi: 3.0

8 info

infoオブジェクトには Web API に関するメタデータを記載する。

title, description, version を必須項目とする。

フィールド名 必須 記載内容
title Web API の総称
description Web API の簡単な説明
version OpenAPI ドキュメントのバージョン
termsOfService 利用規約の URL
contact 連絡先情報
license ライセンス情報

8.1 info > title

Web API の総称を記載する。

システム名やサービス名 + API のような命名を推奨する。

良い例:

info:
  title: X System API

8.2 info > description

Web API が提供する機能の概要・想定する利用者やユースケース・制約などを記載する。

8.3 info > version

この API 仕様のドキュメントのバージョンを記載する。

アプリケーションのバージョン(git tag やリリースで管理するようなバージョン)とは別である。

9 servers

Web API を提供するサーバの情報を記載する。

良い例:

servers:
  - url: http://localhost:8001/
    description: Localhost Server
  - url: https://dev.api.example.com/v1
    description: Development Server
  - url: https://staging.api.example.com/v1
    description: Staging Server

悪い例:

servers:
  - url: https://prod.api.example.com/v1
    description: Production Server

10 paths

API の利用可能なエンドポイントと操作方法を記載する。

フィールド名 必須 記載内容
tags API の論理的なグループ
summary API の操作概要
description API の振る舞いの詳細や注意点
externalDocs API に関する追加の文書
operationId API の利用可能なエンドポイントと操作方法
parameters API のリクエストパラメータ
requestBody API のリクエストボディ
responses API のレスポンス
callbacks
deprecated API が非推奨であることの宣言
security API のセキュリティ機構
servers API に対応する代替サーバ

10.1 paths > {path} > {method} > tags

API の論理的なグループを指定する。

10.2 paths > {path} > {method} > summary

API の操作概要を記載する。

10.3 paths > {path} > {method} > description

API の振る舞いの詳細や注意点を記載する。

別途参照させるべき設計書があるのであれば、設計書へのリンクを記載しても良い。

良い例:

paths:
  /users:
    get:
      description: [API詳細設計書(API-001)](https://example.com/API-001.md)

10.4 paths > {path} > {method} > operationId

API を識別するための一意な文字列を記載する。

10.5 paths > {path} > {method} > parameters

API のリクエストパラメータを記載する。

10.6 paths > {path} > {method} > requestBody

API のリクエストボディを記載する。

10.7 paths > {path} > {method} > responses

API のレスポンスを記載する。

10.8 paths > {path} > {method} > security

API の認証方式を記載する。

11 components

API 定義で利用する共通のデータモデルを定義する。定義方針は下記の通りである。

フィールド名 方針
schemas API 共通的なリソース(例. ユーザや商品など)やエラー等のドメインオブジェクトを定義する
responses API 共通的なレスポンス(例. 異常系(4xx, 5xx)のレスポンス)を定義する
parameters API 共通的なリクエストパラメータ(HTTP ヘッダやクエリパラメータ等)を定義する
examples 原則何も定義しない
requestBodies 原則何も定義せず、リクエストボディは API 個別に定義する
headers API 共通的なレスポンスヘッダを定義する
securitySchemes 標準で用いる API 認証のスキームを定義する
links 原則何も定義しない
callbacks 原則何も定義しない

※ リクエストボディやレスポンスボディにおいてオブジェクトがネストする場合、 API 固有のオブジェクトであっても schemas に定義する。 これは、定義するオブジェクトの properties 配下に更に type: object が定義される場合に、生成ツールによってはうまく型が生成されないためである。 生成ツール上問題ないのであれば、API 固有のオブジェクトを schemas に定義する必要はない。

11.1 components > schemas

API 共通的なリソースやエラー等のドメインオブジェクトを記載する。

良い例:

components:
  schemas:
    # 共通で使用するリソースを表すオブジェクト
    Product:
      type: object
      properties: ...
    User:
      type: object
      properties:
    # 共通で使用するエラーを表すオブジェクト
    ProblemDetailError:
      type: object
      properties: ...

11.2 components > responses

API 共通的なレスポンスを記載する。主に異常系(4xx, 5xx)のレスポンスを定義する。

良い例:

components:
  schemas:
    ProblemDetailError:
      type: object
      properties:
        ...
  responses:
    # HTTP ステータスコード 400 のレスポンスオブジェクト
    BadRequest:
      description: 400 Bad Request
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ProblemDetailError"
    # HTTP ステータスコード 401 のレスポンスオブジェクト
    Unauthorized:
      description: 401 Unauthorized
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/ProblemDetailError"
    ...

正常系のレスポンスの例としてはファイルアップロード・ダウンロードのレスポンスなどが該当する。
個別のアプリケーション要件でブレが少なく、複数のエンドポイントで用いられる場合に定義する。オブジェクトのスキーマは、schemas に切り出して定義し、コード生成ツールのために型情報を付与させる。

良い例:

components:
  schemas:
    SignedURL:
      type: object
      properties:
        signed_url:
          type: string
          format: uri
        expired_at:
          type: string
          format: date-time
  responses:
    BlobUpload:
      description: BLOB(Binary Large Object) upload using presigned url
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/SignedURL"
    BlobDownload:
      description: BLOB(Binary Large Object) download using presigned url
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/SignedURL"
    ImageBinary:
      description: An image
      content:
        image/*:
          schema:
            type: string
            format: binary

11.3 components > parameters

API 共通的なリクエストパラメータ(パスパラメータ、クエリパラメータ、ヘッダ, Cookie)を記載する。

11.3.1 パスパラメータ

11.3.2 クエリパラメータ

良い例:

paths:
  get:
    /products:
      parameters:
        - $ref: "#/components/parameters/QueryLimit"

components:
  parameters:
    QueryLimit:
      name: limit
      in: query
      required: false
      schema:
        type: integer
      description: 検索数上限

11.3.3 ヘッダ

良い例:

paths:
  post:
    /products:
      parameters:
        - $ref: "#/components/parameters/HeaderContentType"

components:
  parameters:
    HeaderContentType:
      name: Content-Type
      in: header
      schema:
        type: string
      required: true

良い例:

paths:
  get:
    /products:
      parameters:
        - $ref: "#/components/parameters/CookieCSRFToken"

components:
  parameters:
    CookieCSRFToken:
      name: csrftoken
      in: cookie
      required: true
      schema:
        type: string
      description: CSRFトークン

11.4 components > requestBodies

原則何も定義せず、リクエストボディは API 個別に記載する。

11.5 components > headers

API 共通的なレスポンスヘッダを記載する。

良い例:

paths:
  get:
    /products:
      responses:
        "200":
          headers:
            XCacheInfo:
              $ref: "#/components/headers/XCacheInfo"

components:
  headers:
    XCacheInfo:
      description: not cacheable; meta data too large
      schema:
        type: string

11.6 components > securitySchemes

標準で用いる API 認証の定義を行う。

良い例:

components:
  securitySchemes:
    # Bearer トークンによる認証
    Bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: "Bearer トークン認証"

links は OpenAPI 3.0 の新機能の1つで、ある API レスポンスの値を用いて、別の API を呼び出す方法を明示できるセクションである。

興味深い機能であり、API のセマンティクスを伝えるのに有用であるが、本規約では記載しないことを推奨とする。

理由:

11.8 components > callbacks

callbacks は OpenAPI 3.0 の新機能の1つで、API サーバ側が指定されたコールバック URL を呼び出すという仕組みである。

仕様書には、EC ショップで購入のたびにマネージャーに通知を送るといった、何かしらの処理をトリガーにコールバック URL を呼び出す例が示されている。

利便性は高い仕様だが、本規約では記載しないことを推奨とする。

理由:

コールバックのような仕組みを実現するには、別途キューイングのメッセージサービスの利用などを検討する。

12 security

全 API に共通で適用されるセキュリティ設定を定義する。

業務システムの Web API において認証が全く存在しないケースは考えにくいため、本規約ではルートレベルで認証を設定し、個々の API への適応漏れを無くす。

良い例:

security:
  - Bearer: []

13 tags

API を論理的にグループ化するためのタグを定義する。

良い例:

tags:
  - name: product
    description: 製品
  - name: user account
    description: ユーザーアカウント

悪い例:

tags:
  - name: products
    description: 製品
  - name: user_account
    description: ユーザーアカウント

14 externalDocs

参照情報としての URL を記載できる。

ただし、description にて参考情報となる URL を記載する方が、複数リンクを指定可能であるなど自由度が高く使いやすいため externalDocs は利用せず description の利用を推奨する。

良い例:

info:
  description: |-
    Some useful links:
    - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
    - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)

# 特別な場合を除き非推奨
externalDocs:
  description: Find out more about Swagger
  url: http://swagger.io

15 ファイル操作

OpenAPI ドキュメントを作成する上でのファイルのアップロード/ダウンロードについて設計上ポイントを記載する。

15.1 ファイルアップロード

Web API におけるファイルアップロードのよく利用される実装手段は、大きく分けて以下の 3 手法に分類できる。

  1. ファイルのコンテンツを Base64 などにエンコードして、JSON の項目として設定し、リクエストボディで送る
  2. multipart/form-data ファイルを送信する
  3. アップロード用に用いる、オブジェクトストレージの Signed URL を発行し、クライアントから直接ファイルをアップロードしてもらう

本規約でファイルアップロードについて上記の 3. Signed URL を推奨する。API 呼び出しとしては次のようなフローとする。

フローの ①、② はアプリケーション固有の紐づけルールにおいて Web API を設計すれば良いため、本規約で YAML の設定例は記載しない。フロー ② については Signed URL を用いたアップロードであり、アプリケーションの Web API 定義を書く必要はない。もし、監査ログなどのガバナンス上、直接オブジェクトストレージへの書き込みを許容されないケースは、B で Signed URL に相当する書き込み先を提供し、B を経由してファイルをアップロードする。

上記どちらのケースも OpenAPI 定義としてはシンプルであるため、記述例は割愛する。

15.2 ファイルダウンロード

ファイルアップロードと同様、オブジェクトストレージの Signed URL 経由を経由してのダウンロードさせる手法を推奨する。Web API としてはオブジェクトストレージにダウンロード用のファイルを書き込み、クライアントが取得するための Signed URL をレスポンスの JSON 項目に渡す方式である。

もし、サムネイルやアイコン画像など、ファイル容量がごく小さい場合は Base64 にエンコードして JSON に埋め込んで渡しても良い。線引をどこに設置するかは本規約で定義しない。

どちらのケースも OpenAPI 定義としてはシンプルであるため、記述例は割愛する。

16 CORS

CORS(Cross-Origin Resource Sharing)のために、options メソッドの追記は 原則不要 とする。

理由:

ただし、Amazon API Gateway のようなサービスを利用する場合は、options メソッドの記載が必須である場合は除く1

17 OpenTelemetry Traceparent HTTP Header

OpenOpenTelemetry で用いるられるtraceparent のリクエストヘッダは OpenAPI で 原則不要 とする。

理由:

18 値が存在しないという状態の表現

原則 null を用いず、パラメータのキー自体を含めないこと(undefined)による表現を行う。

詳細はフューチャー技術ブログ記事を参照されたい

19 バリデーション

パラメータのバリデーションをどこまで厳密に定義すべきかという議論はしばしば行われる。

リクエストパラメータの各項目に対して、必須・型・桁・区分値・日付・正規表現のチェックが行える。レスポンスで用いるモデルについても同様に設定でき、enum, pattern 以外は API の利用者(クライアント)側の DB 設計などに必要な型桁情報を渡すのに有用であるため、できる限り詳しく指定する。

19.1 必須

必須パラメータのみ required: true を定義する

19.2 デフォルト値

パラメータにデフォルト値がある場合はdefault を定義する。

# ex. enum
name: limit
type: number
format: integer
minimum: 1
maximum: 100
default: 20
description: 検索結果の項目数上限(1~100が指定可能)

【注意】API 公開後に、default 値を変更してはならない(API の互換性が崩れるため)。もし変更する場合は、API のバージョンを上げること。

19.3 型・フォーマット

型(type)は string(文字列), number(数値), integer(整数値), boolean(真偽値) array(配列) のうちどれか指定する。

フォーマット(format)は以下の型の詳細情報を示すもので、可能な限り設定する。

OpenAPI 3.0 では 2.0 に存在した file type は存在しない。もし同等の指定をしたい場合は、以下の様に指定する。

type: string
format: binary # binary file contents

19.4

データ型によって、利用できる桁を指定する項目が異なる。可能な限り設定する。

【注意】API 公開後に、レスポンスの maxLength を以前より大きい値に変更してはならない。レスポンスの maxLength など API 利用者側システムの DB の ERD 定義のインプットになる事が多いため。もし行う場合は API のバージョンを上げることや、連携先に桁数変更の旨を調整するなどの考慮を行う。

19.5 区分値

区分値の場合は enum 属性を利用し、descriptionには区分値の論理名を記載する。

name: gender
type: string
enum: ["0", "1", "2", "9"]
description: |
  性別
    0: 不明
    1: 男
    2: 女
    9: 適用不能

OpenAPI 3.0 では区分値の再利用ができるため、横断的に用いる区分値は components 側で定義する。

paths:
  /products:
    get:
      parameters:
        - in: query
          name: gender
          required: true
          schema:
            $ref: "#/components/schemas/Gender"
components:
  schemas:
    Gender:
      type: string
      enum: ["0", "1", "2", "9"]

19.6 固定値

固定値 の場合も enum を 1 つだけ指定して表現する。この場合もレスポンスで利用する場合は指定しない

name: file_layout
type: string
enum: ["json"]
description: ファイルレイアウト

19.7 その他(正規表現)

正規表現で表現できる文字列はpatternを利用して定義する。桁や区分値で代替できる場合は、pattern を用いない

例:

remind_time:
  type: string
  description: リマインド時刻。(hh:mm)形式
  example: 23:59
  pattern: "^(2[0-3]|[01][0-9]):([0-5][0-9])$"

20 ファイル分割

OpenAPI ドキュメントは単一のファイルで構成することも複数の分割されたファイルで構成することもできるが、複数のファイルに分割することを推奨する。

理由:

20.1 分割方法の選定

開発方針や OpenAPI の使用用途に合わせて、都合の良いファイルの分割方法を採用する。例えば、以下のような方法がある。

  1. API path ごとに設計担当者を分けて、それぞれに OpenAPI を編集する場合は、path の単位で分割する。
  2. テストツールとして stoplightio/prismを使用する場合、テストケースごとにデータファイルを作成して、examples にファイルパスを指定する。

注意点:

20.2 サンプル説明

分割方法 1, 2 の両方に当てはまる場合のサンプルを用いて説明する。openapi.yaml とディレクトリ構成は下の通り。全量は sample_dividedを参照すること。


21 License

CC-By-4.0


  1. https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/enable-cors-for-resource-using-swagger-importer-tool.html↩︎