今回は「OpenAPI Specification の使い方」についてまとめます。 OpenAPIに触れるとでてくる Swagger についても、位置づけや役割もあわせてまとめています。
概要
OpenAPI とは
REST API を設計する際に使う「API設計書記述の仕様」です。
OpenAPI Specification を使ってAPIを定義すると「利用可能なエンドポイントおよびそのエンドポイントで可能な操作のイン/アウト」を定義できます。
OpenAPIを使った仕様書は JSON か YAML 形式で記述します。
Swagger とは
Swaggerとは「OpenAPI Specification を使って設計/開発を行うためのツール群」です。 主要なツールは以下の3ツールです。
- Swagger Editor
- ブラウザ上で利用可能なOpenAPIに従った記述を行うためのエディタ
- Swagger UI
- 作成したOpenAPI仕様書をもとにAPIドキュメントとして表示させるビューア
- Swagger Codegen
- 作成したOpenAPI仕様書をもとにスタブやクライアントを作成するジェネレータ
上記ツールはいずれもGitHub上で公開されており、DockerHubにもイメージが公開されています。 中身や使い方が確認したければ GitHub を確認し、とりあえず利用したければ DockerHub のイメージを利用するのがよさそうです。
データ型
基本的にはJSONスキーマに従ったプリミティブ型が利用可能です。 OpenAPIでは一般的な「型」に加えて「フォーマット」が指定できます。 「フォーマット」を使うとより柔軟な型定義ができます。
type | format | 説明 |
---|---|---|
integer |
int32 |
符号付き32ビット整数。 |
integer |
int64 |
符号付き64ビット整数。 いわゆる long 型。 APIのレスポンスではうまく処理できないケースがあるので文字列にすることも考える。 |
number |
float |
浮動小数。 |
number |
double |
倍精度浮動小数。 |
string |
― | 文字列。 |
string |
byte |
Base64エンコードされた文字列。 |
string |
binary |
バイナリ文字列。 |
boolean |
― | 真偽。 |
string |
date |
RFC3339のfull-date形式文字列(=W3C-DTFのComplete Date)。 YYYY-MM-DD(例: 1997-07-16)。 |
string |
date-time |
RFC3339のdate-time形式文字列(=W3C-DTFのComplete date plus hours, minutes and seconds)。 YYYY-MM-DDThh:mm:ssTZD(例: 1997-07-16T19:20:30+01:00)。 |
string |
email |
メールアドレス。 |
string |
password |
パスワード。 |
string |
uuid |
UUID。 |
基本構造
OpenAPI Specification の基本構造は以下のようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | openapi: "3.0.0" info: ... servers: ... tags: ... paths: ... components: ... |
フィールド | 型 | 説明 |
---|---|---|
openapi | string | 必須 OpenAPIのどのバージョンを利用して記述しているかを定義する。 バージョンはセマンティックバージョニングで定義されており、記述もセマンティックバージョニングに従って記述する。 |
info | object | 必須 APIのメタデータを定義する。 |
servers | [object] | APIを提供するサーバーを配列で記述する。 |
tags | [object] | APIを整理するために利用するタグを定義する。 |
paths | object | 必須 APIとして利用可能なパスおよび操作を定義する。 |
components | object | いろいろなオブジェクトをコンポーネントとして再利用可能な形で定義する。 |
スキーマ詳細
info
info
には、API自体のメタデータを定義します。
1 2 3 4 | info: title: "Sample API" description: "Sample API provides sample function." version: "1.0.0" |
フィールド | 型 | 説明 |
---|---|---|
title | string | 必須 APIのタイトルを定義する。 |
description | string | APIに関する説明を定義する。マークダウンを使ってリッチテキスト表示もできる。 |
versioin | string | 必須 記述しているAPI設計書(openapi.yaml自身)のバージョン。 |
servers
APIを提供しているサーバーを定義します。 開発環境であれば localhost 、他にもステージングやプロダクションなどを定義します。
1 2 3 4 5 | servers: - url: "http://localhost:3000" description: "Local machine" - url: "http://api.sample.com" description: "Production Server" |
フィールド | 型 | 説明 |
---|---|---|
url | string | 必須 APIを提供しているサーバーアドレスを記載する。 |
description | string | 提供サーバーに関する補足情報を記載する。 |
tags
APIを整理するために使用するタグを配列で定義します。
ここで定義されたタグは定義された順に表示されます。
APIで利用するタグすべてを定義する必要はありませんが、自動作成されるタグはここで定義されたタグの後ろに追加されます。
タグなしのAPIは default
という名前のタグが割り当てられます。
1 2 3 | tags: - name: "shops" description: "Shop operations." |
フィールド | 型 | 説明 |
---|---|---|
name | string | 必須 タグ名を定義する。 |
description | string | タグに関する説明を記載する。 マークダウンを利用したリッチテキスト表記も可能。 |
paths
APIとして利用可能なパスおよび操作の実態を定義します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | paths: "/shops/{shopId}/reviews": post: summary: "Create new review." description: "Add new specified shop's review." tags: ["shops"] deprecated: false parameters: - name: "shopId" in: "path" description: "Specified shop ID" required: true schema: { type: string } requestBody: description: "Review contents" required: true content: application/json: schema: type: object properties: score: { type: integer, format: int32 } comment: { type: string } responses: 201: description: "Success response" security: - sample_oauth2_auth: ["create_review"] |
少し量が多いので以下のように分割して見ていきます。
- パス、メソッド、操作
- リクエストパラメータ
- リクエストボディー
- レスポンス
- セキュリティ
パス、メソッド、操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | paths: "/shops/{shopId}/reviews": post: summary: "Get specified shop's reviews." description: "Get specified shop's reviews." tags: ["shops"] deprecated: false parameters: ... requestBody: ... responses: ... security: ... |
フィールド | 型 | 説明 |
---|---|---|
{path} | object | エンドポイントになる相対パスを定義する。
パスは必ず "/"(スラッシュ) から始まるよう記述する。
パスパラメータを指定したい場合、 "{} "(波括弧) で表現する。 |
{path}.{method} | object | パスに対する操作を定義する。
定義できる操作は以下の通りで、 connect 以外が利用可能です。
|
{path}.{method}.summary | string | 操作に関する簡単な説明を記載します。 |
{path}.{method}.description | string | 操作に関する詳細説明を記載します。 マークダウンを利用してリッチテキスト表記もできる。 APIの処理詳細を記載します。マークダウン形式で記載ができます。 |
{path}.{method}.tags | [string] | タグを配列で言指定する。 タグをつけることでAPIをグルーピングすることができます。 |
{path}.{method}.deprecated | boolean | 廃止になった操作かどうかを定義します。
デフォルト false 。 |
{path}.{method}.parameters | object | リクエストパラメータ情報を定義します。 |
{path}.{method}.requestBody | object | リクエストボディー情報を定義します。 |
{path}.{method}.responses | object | レスポンス情報を定義します。 |
{path}.{method}.security | object | セキュリティに関する定義をします。 |
リクエストパラメータ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | paths: "/shops/{shopId}/reviews": get: ... parameters: - name: "shopId" in: "path" description: "Specified shop ID" required: true schema: { type: "string", format: "uuid" } - name: "order" in: "query" description: "Response sort order" required: true schema: type: string enum: ["asc", "desc"] responses: ... security: ... |
フィールド | 型 | 説明 |
---|---|---|
name | string | 必須 パラメータ名を指定します。 in: path の場合、パス中のパラメータ名と一致させる必要があります。 |
in | string | 必須 パラーメータの場所を指定します。 指定できる値は以下の通りです。
|
description | string | パラメータに関する説明を記載します。 マークダウンも利用可能です。 |
required | boolean | in: path の場合は 必須パラメータの必須/非必須を定義します。 デフォルトは false 。 |
schema | object | パラメータの型定義をします。 JSONスキーマを元にした記述をします。 |
リクエストボディー
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | paths: "/shops/{shopId}/reviews": post: ... parameters: ... requestBody: description: "Review contents" required: true content: application/json: schema: type: object properties: score: { type: integer } comment: { type: string } responses: ... security: ... |
フィールド | 型 | 説明 |
---|---|---|
description | string | リクエストボディーに関する説明を記載します。 |
required | boolean |
リクエストボディーが必須かどうかを指定します。デフォルトは false 。 |
content | object | 必須 リクエストボディーの内容を定義します。 値に設定できるのは Media-Type を値。 |
content.{media} | object | メディアタイプをキーにレスポンスボディーを定義します。 |
content.{media}.schema | object | リクエストボディーの定義をします。 JSONスキーマを元にした記述をします。 |
レスポンス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | paths: "/shops/{shopId}/reviews": get: ... parameters: ... responses: 200: description: "Success response." headers: X-RateLimit-Remaining: description: "Number of remaining requests in the currenct period." schema: { type: integer } content: application/json: schema: type: array items: type: object properties: score: { type: integer } comment: { type: string } security: ... |
フィールド | 型 | 説明 |
---|---|---|
{status} | object | {status}に定義したいステータスコードを指定します。 ステータスコードをキーとしてレスオンスの内容を定義します。 |
{status}.description | string | 該当ステータスコードのレスポンス概要を記載します。 |
{status}.headers | object | レスポンスに含まれるヘッダーを定義します。 |
{status}.headers.{header} | object | {header}に定義したいヘッダー名を指定します。 ヘッダー名をキーとしてヘッダー情報の内容を定義します。 |
{status}.headers.{header}.description | object | レスポンスヘッダーの概要説明を記載します。 |
{status}.headers.{header}.schema | object | レスポンスヘッダーのスキーマを定義します。 |
{status}.content | object | レスポンスの中身を定義します。 |
{status}.content.{media} | object | レスポンスのメディアタイプをキーに内容を定義します。 |
{status}.content.{media}.schema | object | レスポンスのスキーマを定義します。 |
セキュリティ
1 2 3 4 5 6 7 8 9 10 11 12 13 | paths: "/shops/{shopId}/reviews": post: ... parameters: ... requestBody: ... responses: ... security: - sample_oauth2_auth: ["create_review"] |
フィールド | 型 | 説明 |
---|---|---|
{name} | [string] | {name} には /components/securitySchemes に定義したセキュリティ名を指定します。 指定する配列には必要とするスコープ名を定義します。 apiKey や http で特にスコープが必要ない場合、空配列にします。 |
components
OpenAPI中で再利用可能なコンポーネントを定義します。 定義できるものとしては以下のようなものがあります。
今回はこのうちよく利用しそうな「schemas
」と「securitySchemes
」を取り上げます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | components: schemas: ... responses: ... parameters: ... examples: ... requestBodies: ... headers: ... securitySchemes: ... |
componentsを利用するときは $ref を使って以下のように参照させます。
1 2 3 4 5 6 7 8 9 10 | paths: "/shops/{shopId}/reviews": post: ... requestBody: ... content: application/json: schema: $ref: "#/components/schemas/Review" |
schemas
-
プリミティブ
123456components:
schemas:
ShopId:
type: string
format: uuid
example: "SAMPLE-SHOP-ID-XXXXXX"
-
列挙
12345components:
schemas:
SortOrder:
type: string
enum: [asc, desc]
-
オブジェクト
1234567891011components:
schemas:
Review:
type: object
example: { score: 4, comment: "Sample review comment." }
properties:
score:
type: integer
format: int32
comment:
type: string
-
配列
123456components:
schemas:
ReviewList:
type: array
items:
$ref: "#/components/schemas/Review"
フィールド | 型 | 説明 |
---|---|---|
{name} | object | スキーマとして定義する任意の名前を指定します。 |
{name}.type | string | 型を定義します。 |
{name}.description | string | スキーマに関する説明を記述します。 |
{name}.format | string | プリミティブ型の場合、追加のフォーマット指定があれば定義します。 |
{name}.enum | [any] | 決められた値から選択される場合、選択可能な値を定義します。 |
{name}.properties | object | type: object の場合、オブジェクトの内容を定義します。 |
{name}.items | object | type: array の場合、配列の内容を定義します。 |
{name}.default | any | デフォルト値を定義します。 |
{name}.example | any | サンプルを定義します。 |
securitySchemes
-
JWT
1234567components:
securitySchemes:
sample_jwt_auth:
type: http
description: "Sample Service original authorization."
scheme: bearer
bearerFormat: JWT
-
API Key
1234567components:
securitySchemes:
sample_apikey_auth:
type: apiKey
description: "Sample Service API-Key authorization."
in: header
name: X-Api-Key
-
OAuth2
12345678910components:
securitySchemes:
sample_oauth2_auth:
type: oauth2
flows:
authorizationCode:
authorizationUrl: "https://oauth.sample.com/auth"
tokenUrl: "https://oauth.sample.com/token"
scopes:
"create_review": "Post new review."
-
OpenIDConnect
12345components:
securitySchemes:
sample_oidc_auth:
type: openIdConnect
openIdConnectUrl: "https://oidc.sample.com/signin"
-
Cookie
123456components:
securitySchemes:
sample_cookie_auth:
type: apiKey
in: cookie
name: JSESSIONID
フィールド | 型 | 説明 |
---|---|---|
type | string | 必須 以下のいずれかを指定します。
|
description | string | セキュリティスキーマの説明を記載します。 |
name | string | type: apiKey の場合、必須ヘッダー、クエリ―、クッキーのキー名を指定します。 |
in | string | type: apiKey の場合、必須APIキーがどこにあるかを以下から指定します。
|
scheme | string | type: http の場合、必須IANAのスキーマレジストリに登録されたものを指定します。 以下のような値が指定できます。
|
bearerFormat | string | type: http, scheme: bearer のとき定義できます。Authorizationヘッダーに入れるフォーマットを指定します。 ほぼ JWT しか入らなさそう。 |
flows | object | type: oauth2 の場合、必須OAuth2 のフローを定義します。 |
flows.{flow} | object | {flow} には以下のいずれかを指定します。
|
flows.{flow}.authorizationUrl | string | {flow}: implicit, authorizationCode の場合、必須認可エンドポイントのURLを定義します。 |
flows.{flow}.tokenUrl | string | {flow}: password, clientCredentials, authorizationCode の場合、必須トークン取得するエンドポイントのURLを定義します。 |
flows.{flow}.refreshUrl | string | リフレッシュトークンを取得するエンドポイントのURLを指定します。 |
flows.{flow}.scopes | objecct | 必須 利用可能なスコープを定義します。 |
flows.{flow}.scopes.{scope} | string | キー({scope})にスコープ名を定義し、バリューに該当スコープの説明を定義します。 |
openIdConnectUrl | string | type: openIdConnect の場合、必須OpenIDConnectディスカバリーのエンドポイントURLを指定します。 |
今回は「OpenAPI Specification の使い方」についてまとめました。 参考になったでしょうか? 本記事がお役に立っていると嬉しいです!!
参考記事
- Swagger - About Swagger Specification
- GitHub - OpenAPI Specification 3.0.3
- Swagger - Authentication and Authorization
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!