拝啓、この記事を読みに来た皆様へ。。
この記事はOpenAPI V3を構成する各要素の説明を乗せた記事が無いことに挫折した僕が、英語で出来ている公式ドキュメントを見ながら書いた記事となります。
英語は難しい!けどOpenAPI V3の構成要素を知りたい!!と言う方のお役に立てれば!!!めちゃくちゃ嬉しいです!!!!
追伸
この記事は要素の説明や制限事項などが書いており、OpenAPIの書き方に関する記事ではありません。
書き方は次の記事で!! (๑´ڡ`๑)
では、始まります。。
ApigeeのSpecでOpenAPIを利用し、Proxy生成!
Apigee&OpenAPIでAPIドキュメント作成が簡単になる!
以前、この二つの記事を通してOpenAPIの使い道を確認して見ました。
ただ、一から作り上げた物を使うのではなくサンプルを使って実施したため、物足りなさを感じながら記事を終わらせたので、今回は物作りのためにOpenAPIを解剖して中身をチェックします。
基本的に使う要素だけを組んで実装するのは難しくないものですが、奥に入ると制約付き要素もあるので軽く見すぎると良くないと思います!!
と!言うことなので、今回の流れは。。
- step1. OpenAPI解剖準備
- step2. OpenAPI解剖
2ステップしかないから簡単そうに見えて実際は結構長い。。。
目次
1.解剖対象のOpenAPIバージョンは?
後々これを活用することになるApigeeのためにV2を見た方が良いと思いましたが、ちょっと古いバージョンなので最新のV3.0.2(2018.10.08にリリース)を解剖することにしました。
’ApigeeはV2を支援すると言うのにV3で解剖したら使えないのでは?’と思いますが、V2に変換してくれるツールが存在するので、実際作業に取り込んだ時はそれを使って乗り越えて見ようと思います。
2.OpenAPIの解剖準備
準備するもの、その1
OpenAPIを作成するファイルフォーマットを決める!!
だけなので特に準備するものはありません。(この記事を通じて何か作るわけではないので、ファイルすらも必要ないのですが。。OpenAPIの基礎知識として知っておこう!)
OpenAPIはJSON又はYAML形式で作成可能で、お互いに変換もできますが、YAMLからJSONに変換するためには下記の制約付きでOpenAPIの作成を推奨しています。
- ベースとなるYAMLのバージョンは1.2
- JSONスキーマルールに記載されているタグを使用すること
- YAMLマップに使用されるキーはYAMLフェイルセーフスキーマルールを元にスカラー文字列に制限する必要がある
引用:公式ドキュメントから
それとファイルの格納先はプロジェクトのルートにopenapi.拡張子(json又はyaml)で保存することを推奨しているので、作業するときはこれに従いましょう。
3.OpenAPIの解剖オペ、開始
まずは注意点!
各要素のフィールド名は決まっている + 英字の大小文字を区別するため、フィールド名をちゃんと確認しましょう。
Swaggerエディターなどを使用する場合、自動補完機能が働いてくれるので作業しやすくはなりますが、配列系のオブジェクトの中では自動補完が働かない(例:Parametersオブジェクト)のとSecurityやExamplesオブジェクトの中でも自動補完が働かないので自動補完は万能ではありません。
自動補完の頼りすぎには注意し、どんな要素で構成されるのかこの記事を参考に作業することをおすすめします!
※ フィールド名が固定されている要素以外に自由記載可能な要素も存在します。
OpenAPIの中身は下記の要素で構成されています。
- OpenAPIのバージョン情報:openapi
- APIの詳細情報:info
- 接続先の情報:servers
- エンドポイント:paths
- 再利用できるオブジェクト集:components
- 認証はこちら:security
- カテゴリ化するためには必須:tags
- 外部文書リンクを追加しよう:externalDocs
上から順番に何でできているのか、確認しながら進みましょう。
3.1.はじめ、APIのメタデータから
使用するOpenAPIのバージョンや、APIに関する情報を記述します。
OpenAPIを利用するツール上で必要な要素がなければ最低限の定義をしてもOKです。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
openapi | 文字列 | YES | semver形式のOpenAPIバージョンを記述、 リビジョンヒストリを参考 ツールでOpenAPIを解釈する時使用される要素 |
info | Info オブジェクト |
YES | APIのメタデータ ツールによって使用される場合がある |
info/ title |
文字列 | YES | APIのタイトル |
info/ description |
文字列 | APIの説明 説明要素は全てCommonMarkを支援する |
|
info/ termsOfService |
文字列 | サービス利用規約、Webページや文書の アドレスを入れる |
|
info/ contact |
Contact オブジェクト |
公開されているAPI担当への連絡先情報 | |
info/ contact/ name |
文字列 | 担当者又は担当組織名 | |
info/ contact/ url |
文字列 | 担当者又は担当組織のURL | |
info/ contact/ |
文字列 | 担当者又は担当組織のEメールアドレス | |
info/ license |
License オブジェクト |
APIのライセンス情報 | |
info/ license/ name |
文字列 | YES | 使用中のライセンス名 |
info/ license/ url |
文字列 | 使用中のライセンス情報URL | |
info/ version |
文字列 | YES | このOpenAPI文書のバージョン 使用されているOpenAPIのバージョンや API実装バージョンではない |
3.2.APIの通信先、サーバ情報
接続対象となるターゲットサーバ集。
配列であるため、複数のサーバを追加することができますが、このオブジェクト自体は必須ではないため、必ず作成する必要はありません。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
servers | Server オブジェクト |
サーバの情報を持つ配列 作成しない場合、このAPIがアップされているサーバのアドレスがベースになる |
|
servers/ url |
文字列 | YES | ターゲットのURL、APIドキュメントが提供されるホストから相対パスの指定も可能、 大括弧`{}`でサーバ変数指定可能 |
servers/ description |
文字列 | URLの説明 | |
servers/ variables |
マップ [文字列, ServerVariable オブジェクト] |
サーバのURLで使用可能な変数のマップ URLに変数名を挿入して変数の値に置換できる |
|
servers/ variables/ enum |
文字列配列 | 置換する値のデータセット、置換対象の値が複数存在する場合使用 | |
servers/ variables/ default |
文字列 | YES | 変数の初期値、enumが定義されている場合はデフォルトが含まれているべし |
servers/ variables/ description |
文字列 | 変数の説明 |
3.3.APIで行われる操作の定義、パス
ここがこのOpenAPIの核心部となるところです。
各パスに対してgetやputなどの操作を定義し、それぞれの操作に対してリクエストやレスポンスの定義もここで行われます。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
paths | Paths オブジェクト |
YES | API操作とパスを定義する 複数実装可能 |
paths/ {path} |
Path Item オブジェクト ※{path}は文字列 |
スラッシュから始まるエンドポイント、 ベースとなるURLの後ろに結合される ACL制約(※)があるので空でもOK、 パスパラメータも支援する |
|
paths/ {path}/ $ref |
Reference オブジェクト |
コンポーネントに定義されているオブジェクトを指定する Path Itemオブジェクトと一致する定義でなければならない、矛盾の発生もだめ ※Referenceオブジェクトが使用される場合、 それが使用されるオブジェクトと同じオブジェクト構成であるべし |
|
paths/ {path}/ summary |
文字列 | パスの概要 | |
paths/ {path}/ description |
文字列 | パスの説明 | |
paths/ {path}/ {http method} |
Operation オブジェクト |
HTTPメソッドの定義、支援するタイプは? get, put, post, delete, options, head, patch, trace 複数のメソッド定義可能 オブジェクトの詳細は別途の表で説明 |
|
paths/ {path}/ servers |
Server オブジェクトリスト |
パス内部で使用される代替サーバリスト 構成は3.2と同一 |
|
paths/ {path}/ parameters |
Parameters オブジェクト 又は Reference オブジェクト のリスト |
パス内部で使用可能なパラメーターのリスト オブジェクトの詳細は別途の表で説明 |
パスオブジェクトを構成する要素の中で、OperationとParametersオブジェクトはサイズが大きいため別途、表で解剖します。
まずは出現頻度が高いパラメータオブジェクトから。
3.3.1.Parametersオブジェクト
パラメータを定義する上で一番重要なものはどの場所にどんなパラメータ名で保存されているのかです。
パスパラメータなのか、ヘッダーに保存されているのかなどを明確にしないといけませんね。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
parameters/ name |
文字列 | YES | パラメータ名、英字の大小文字を区別する ’in’に設定されているパラメータ格納先に設定 されたパラメータ名と同一でなければならない |
parameters/ in |
文字列 | YES | パラメータが設定される場所を指定する “query”, “header”, “path”, “cookie” |
parameters/ description |
文字列 | パラメータの説明 | |
parameters/ required |
ブーリアン | パラメータに必須設定をする inがpathの場合、この要素は必ずtrueを設定 する、そうでないと初期値がfalseになる |
|
parameters/ deprecated |
ブーリアン | 廃止される予定の場合に設定する | |
parameters/ allowEmptyValue |
ブーリアン | inがqueryの場合に有効で空の値を渡すことが できるようになる styleが指定され直列化できない値の場合 これは無視される この要素は削除予定なので使用するのは非推奨 |
パラメータを直列化(シリアルライズ)をするためには下記の項目が必要です。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
parameters/ style |
文字列 | 指定したスタイルによってデータの直列化 方式が変わる ※スタイル指定に関して |
|
parameters/ explode |
ブーリアン | 配列又はマップのキー、値ペアが一緒に生成 されるか別々に生成されるかが決まるstyleが formの場合、初期値はtrueその他はfalseになる |
|
parameters/ allowReserved |
ブーリアン | queryの場合有効な要素 予約語をパーセントエンコディングなしで 含められるようにするかを指定 |
|
parameters/ schema |
Schema オブジェクト 又は Reference オブジェクト |
パラメータで使用される型を定義する プリミティブ型、配列なども定義可能なので 詳細と使用例を参照 |
|
parameters/ example |
自由記載 | どんな形の値を入れるのか値の例や説明を記載 ※example(単数)又はexamples(複数) の内にパラメータによって使い分ける |
|
parameters/ examples |
マップ [文字列、 Example オブジェクト 又は Reference オブジェクト] |
複数の要素で構成されているパラメータの例を 記載する、定義されているパラメータの正しい フォーマットを含んで定義すること |
|
parameters/ examples/ summary |
文字列 | 例の概要 | |
parameters/ examples/ description |
文字列 | 例の説明 | |
parameters/ examples/ value |
自由記載 | 値の入力例を記入 | |
parameters/ examples/ externalValue |
文字列 | リテラルで参照可能な外部文書のURL |
より複雑な構造を持つパラメータを指定するのであればコンテンツを使うと良いでしょう。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
parameters/ content |
マップ[文字列、 Media Type オブジェクト] |
マップ形式でパラメータを定義する 最低限一つのエントリが必要、Parameters オブジェクト内部ではSchemaとContentの どっちか一つのみ利用すること |
|
parameters/ content/ schema |
Schema オブジェクト 又は Reference オブジェクト |
Contentオブジェクトの中ではリクエスト、 レスポンス又はパラメータを定義する時に使う |
|
parameters/ content/ example |
自由記載 | Parametersオブジェクトの説明を参考 | |
parameters/ content/ examples |
マップ[文字列、 Example オブジェクト 又は Reference オブジェクト] |
Parametersオブジェクトの説明を参考 | |
parameters/ content/ encoding |
マップ[文字列, Encoding オブジェクト] |
Schemaオブジェクトで指定したパラメータの オブジェクト形式を定義する、詳細はこちら |
3.3.2.Operationオブジェクト
HTTPメソッドの定義を行います。
ここではフィールドがどこの配下に位置するのかを明確にするため、postメソッドだと仮定してフィールド名を記載しました。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
post/ tags |
文字列リスト | API管理用タグリスト 修飾子を作成し論理的なグループを作る |
|
post/ summary |
文字列 | 操作の概要 | |
post/ description |
文字列 | 操作の説明 | |
post/ externalDocs |
External Documentation オブジェクト |
この操作に関する外部資料を追加 | |
post/ externalDocs/ description |
文字列 | 外部資料の説明 | |
post/ externalDocs/ url |
文字列 | YES | 外部資料のURLを記載 |
post/ operationId |
文字列 | 操作の識別用ID、IDは一般的なプログラミング命名規則を利用して作成することを推奨されています API文書内でIDが被らないようにしないと行けません、英字の大小文字も区別 |
|
post/ parameters |
Parameters オブジェクト 又は Reference オブジェクト のリスト |
Pathsオブジェクトにparametersが定義されている場合、それをオーバーライドする 構成は3.3.1を参照 |
|
post/ requestBody |
Request Body オブジェクト 又は Reference オブジェクト |
操作内で使用されるリクエストボディ | |
post/ requestBody/ description |
文字列 | リクエストボディの説明 | |
post/ requestBody/ content |
マップ [文字列、 Media Type オブジェクト] |
YES | リクエストボディの内容 構成の詳細は3.3.1のcontentを参照 |
post/ requestBody/ required |
ブーリアン | リクエストボディに必須設定をする | |
post/ responses |
Responses オブジェクト |
YES | 操作後に返される可能性があるレスポンスのリスト 必ず一つ以上のレスポンスを定義する(最低限の定義として正常処理が必要) 別途の表で解剖を続ける |
post/ callbacks |
マップ [文字列、 Callback オブジェクト 又は Reference オブジェクト] |
コールバック処理を実装する | |
post/ callbacks/ {expression} |
Path Item オブジェクト |
※{expression}:コールバックされる対象 runtimeExpressionで指定 内部はOperationオブジェクトで構成されている |
|
post/ deprecated |
ブーリアン | 廃止される予定の場合に指定する | |
post/ security |
Security Requirement オブジェクト リスト |
コンポーネントオブジェクトの配下で実装したセキュリティースキームを指定する “oauth2″と”openIdConnect”の場合はスコープ名を入れてあげる、例(sec[userInfo, productList]) 構成は3.5を参照 |
|
post/ servers |
Server オブジェクト リスト |
操作内部で使用可能な代替サーバ情報 パスオブジェクト直下に定義されているServerオブジェクトをオーバーライドする 構成は3.2を参照 |
Responsesオブジェクト
※ステータスコードは’200’を仮定してフィールド名を記載します。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
default又は HTTP ステータス コード |
Response オブジェクト 又は リファレンス オブジェクト |
レスポンスに設定されているステータスコード や未定義のステータスコード(デフォルト が働く)に対してレスポンス処理を記載する ワイルドカード使用可能、 引用符としてXを使う(例:2XX、3XX) 引用符を使うコードの定義より明確なコード が定義されている場合はそれが優先される |
|
‘200’/ description |
文字列 | YES | ステータスの説明 |
‘200’/ headers |
マップ [文字列、 Header オブジェクト 又は Reference オブジェクト] |
Parametersオブジェクトと同じ構成だが、 一部が違う name要素は不要、マップのキーがnameとなる in要素も不要、暗黙的にheaderになるため 上記二つ以外の要素はinがheaderだと言う 前提条件を守らないと行けません |
|
‘200’/ content |
マップ [文字列、 Media Type オブジェクト] |
3.3.1のcontentの説明を参考 | |
‘200’/ links |
マップ [文字列、 Link オブジェクト 又は Reference オブジェクト] |
レスポンスから繋がる操作のリンクマップ マップのキーはコンポーネントオブジェクト の命名規則に従う |
|
‘200’/ links/ operationRef |
文字列 | 外部又は内部に定義されているAPIを指定可能、 ただ内部APIを指定すると値が読み難くなる ため、外部API指定を推奨 |
|
‘200’/ links/ operationId |
文字列 | 内部に定義されているAPIを指定することが できる、指定されているIDを使用する操作に 繋がる内部のリンクはoperationRefより こちらを推奨 |
|
‘200’/ links/ parameters |
マップ [文字列、 自由記載又は {expression}] |
リンク先に渡すパラメータを設定 パラメータ名がキーとなり値は定数又は runtimeExpressionで指定可能 |
|
‘200’/ links/ requestBody |
自由記載又は {expression} |
ターゲットに渡されるリクエストボディ runtimeExpressionで指定可能 |
|
‘200’/ links/ description |
文字列 | リンクの説明 | |
‘200’/ links/ server |
Server オブジェクト |
ターゲットサーバを定義 |
3.4.再利用するための定義集、コンポーネント
Referenceオブジェクトが参照するオブジェクトをここで定義します。
オブジェクト定義後、参照可能なオブジェクトは九つ存在!
- schemas
- responses
- parameters
- examples
- requestBodies
- headers
- securitySchemes
- links
- callbacks
詳細はこちらを参照、どう言う形で実装をするのかを参考にすると良いです。
3.5.大事な認証処理、セキュリティー
認証が必要な場合はこのオブジェクトが必要になりますが、作り方が他のオブジェクトちょっと違います。
※認証の深い話はSwaggerのウェブサイトを参照
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
security | Security Requirement オブジェクト リスト |
認証に必要なものを定義する | |
security/ {name} |
文字列リスト ※{name}は文字列 |
コンポーネントオブジェクトの配下で実装した セキュリティースキームを指定する “oauth2″と”openIdConnect”の場合は スコープ名を入れてあげる (例:{”sec”: [“userInfo”, “productList”]}) |
セキュリティーオブジェクトはコンポーネントのセキュリティースキームを参照する様になってます。
なので、中身を確認するにはセキュリティースキームを解剖しないといけません。
※各要素のフィールド名に”securitySchemes”の記載を省略する
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
security Schemes |
マップ [文字列、 Security Scheme オブジェクト 又は Reference オブジェクト] |
コンポーネント内部で定義される 認証設定用オブジェクト |
|
type | 文字列 | YES | 認証種類を記載する、有効なものは “apiKey”, “http”, “oauth2”, “openIdConnect” |
description | 文字列 | 認証の説明 | |
name | 文字列 | YES | “type: apiKey”限定 inで指定された場所に設定されている パラメータ名 |
in | 文字列 | YES | “type: apiKey”限定 パラメータが設定される場所を指定する 有効なのは”query”, “header” or “cookie” |
scheme | 文字列 | YES | “type: http”限定 Authorizationヘッダーで使用されるHTTP Authorization方式の名前、bearer時も使用 |
bearerFormat | 文字列 | “type: http(bearer)”限定 トークのフォーマットを指定するサーバ から生成されるトークンのフォーマット 情報をここに記載(例:JWT) |
|
flows/ {flow} |
OAuth Flows オブジェクト |
YES | “type: oauth2”限定 OAuth認証フロー、支援するフローは ”implicit”, “password”, “clientCredentials”, “authorizationCode” 複数のフローが指定可能だが、各フロー別 に一つしか定義できない |
flows/ {flow}/ authorizationUrl |
文字列 | YES | “flow: implicit, authorizationCode”限定 認証サーバのURL |
flows/ {flow}/ tokenUrl |
文字列 | YES | “flow: password, clientCredentials, authorizationCode”限定 トークン発行URL |
flows/ {flow}/ refreshUrl |
文字列 | トークン更新用URL | |
flows/ {flow}/ scopes |
マップ [文字列, 文字列] |
YES | OAuth2方式で利用可能な機能、権限、 スコープの説明を記載 |
openId ConnectUrl |
文字列 | YES | “type: openIdConnect”限定 OAuth2設定値を検出するためのURL |
3.6.各操作をカテゴライズしよう、タグ
タグは各Operationオブジェクトの内部で定義しても良いが、一足先にAPI全体に反映されるタグを定義することも可能です。
但し、操作内部で定義する全てのタグをここで定義してあげる必要はないので、基本的なものだけ定義するのも良いと思います。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
tags | Tag オブジェクト リスト |
各操作と結びつけるタグを定義する | |
tags/ name |
文字列 | YES | タグ名 |
tags/ description |
文字列 | タグの説明 | |
tags/ externalDocs |
External Documentation オブジェクト |
このタグに関する外部資料を追加 |
3.7.最後は!?外部文書
ここではAPI文書全体に関する外部資料を追加しましょう。
フィールド名 | データタイプ | 必須 | フィールド説明 |
---|---|---|---|
externalDocs | External Documentation オブジェクト |
API文書に関する外部資料を追加 構成は3.3.2のexternalDocsを参照 |
まとめ
苦手な英語でできている文書を見ながら理解しようとしたので、かなり難しい作業となりました。中身の構成とかも理解しないと行けないのでまだまだ勉強は続きますが、この記事がOpenAPI V3を理解するにあたって役に立つものになると嬉しいです!
まず最初の一歩として中身の確認を行い、次は物作りに入ろうと思います。
なので次の記事は。。。OpenAPI作成、基本構造を作る編。。。
次の記事で会いましょう〜