OpenAPI再入門
OpenAPIとは?
RESTFul APIの仕様のこと。略語はOAS。今回確認したのは最新のVersion 3.0.3。yamlもしくはjsonファイルで記述し、APIの仕様を定義することができる。
スキーマと呼ばれるオブジェクト(データモデル)が存在し、各オブジェクトでどのようなフィールドを持つことができるのかはドキュメントのFixed Fields
の欄で確認することができる。
オブジェクトの一部のフィールドには接頭辞のx-
をつけることでベンダー独自の仕様拡張が可能となっている。拡張可能なフィールドに関してもopenapiの仕様書に定義されている。
構造
ルートの定義
APIのルートパスに関してはopenapiのスキーマであるServer
オブジェクトで定義する。url
やdescription
がserverオブジェクトのフィールドにあたる。
以下のように複数の環境を定義できる。
servers: - url: http://api.example.com/v1 description: "本番環境" - url: http://staging-api.example.com description: "ステージング環境"
このurl
フィールドの定義はサーバーのベースパスとなる。
url
フィールドの任意の部分には変数を渡すこともできる。変数を渡したいときはvariables
フィールドに必須のdefaultフィールドを設定し、オプションのenumをセットする。
servers: - url: '{protocol}://api.example.com' variables: protocol: enum: - http - https default: https
全てのスキーマに対して言えることだが、Fixed Fields
のtype
(データ型)に他のオブジェクトが設定されていた場合、そのフィールドは他のオブジェクトを持つことができる。(オブジェクトは定義に従った入れ子構造にできる)
例えばServer
オブジェクトのフィールドにはvariables
フィールドが定義されているが、これはServer Variable
オブジェクトという別のオブジェクトであり、Server Variable
オブジェクトがどのようなフィールドを持つことができるかはServer Variable
オブジェクトのFixed Fields
に従う。
その他のOASのプリミティブなデータ型についてはJSON Schema Specification Wright Draft 00 でサポートされている型に基づいている。
Paths
エンドポイントに対して、複数のHTTPメソッド(操作)を定義できる。
例:
paths: /users/{id}: get: ... patch: ... delete: ...
エンドポイント
フィールド名は/
で始まる必要がある。このエンドポイントはベースURLに対して相対的なもの。
例えばエンドポイントを/users
のように設定し、serverのベースURLをhttps://api.example.com/v1
のように設定している場合、エンドポイントはhttps://api.example.com/v1/users
として参照される。{id}
のように中括弧を利用してURLの一部をパスパラメータとして利用することもできる(パステンプレート)。その場合、APIクライアントはhttps://api.example.com/v1/users/5
などと適切なパラメータを提供する必要がある。
HTTPメソッド(操作)
GET、POST、DELETE などのHTTPメソッド。
また、OpenAPIの「操作(operations)」の定義にはパラメータ、リクエストボディ、レスポンスのステータスコード(200 OK または 404 Not Found など)、レスポンスの内容が含まれる。
Pathの定義と入れ子構造
Pathの項目でパラメータ、レスポンス、ステータスコードを定義した場合、以下のような形になる
paths: /users/{id}: get: parameters: - name: id in: path required: true schema: type: integer format: int64 responses: '200': content: application/json: schema: $ref: '#/components/schemas/User' components: schemas: User: type: object properties: id: type: integer format: int64 name: type: string required: - id - name
それぞれのフィールドを分解してコメントを入れるとこんな感じ。
paths: # pathsオブジェクト /users/{id}: # pathオブジェクトのフィールド(Path Itemオブジェクト) get: # Path Itemオブジェクトのフィールド(Operationオブジェクト) parameters: # Operationオブジェクトのフィールド(Parameterオブジェクト) - name: id # Parameterオブジェクトのフィールド(string) in: path # Parameterオブジェクトのフィールド(string) required: true # Parameterオブジェクトのフィールド(boolean) schema: # Parameterオブジェクトのフィールド(Schemaオブジェクト) type: integer # Schemaオブジェクトのプロパティ format: int64 # Schemaオブジェクトのプロパティ responses: # Operationオブジェクトのフィールド(Responsesオブジェクト) '200': # Responsesオブジェクトのフィールド(Responseオブジェクト) content: # Responseオブジェクトのフィールド(Map[string, Media Typeオブジェクト]) application/json: # Map[string, Media Typeオブジェクト]型のキー(string) schema: # Media Typeオブジェクト型のフィールド(Schemaオブジェクト) $ref: '#/components/schemas/User' # Referenceオブジェクト ... components: # Componentsオブジェクト schemas: # Componentsオブジェクトのフィールド(Map[string, Schemaオブジェクト]) User: # Map[string, Schemaオブジェクト]型のキー(string) type: object # Schemaオブジェクトのプロパティ properties: # Schemaオブジェクトのプロパティ id: # Schemaオブジェクト type: integer # Schemaプロパティ format: int64 # Schemaプロパティ name: # Schemaオブジェクト type: string # Schemaプロパティ required: # Schemaオブジェクトのプロパティ - id - name
※Schemaオブジェクトに関してはフィールドという表現ではなく、プロパティという表現になっている。こちらのプロパティについてもJson Schemaに基づき定義されている。