$ref の使用
API をドキュメント化する際、複数の API リソースで利用する共通の機能があることがよくあります。その場合、そのような要素の断片を作成し、必要なときに何度も使用することができます。OpenAPI 3.0 では、任意の場所(同じサーバー、GitHub、SwaggerHubなど)にホストされている定義を参照できます。定義を参照するには、$ref
キーワードを使用します。
1$ref: "reference to definition"
たとえば、レスポンス内で使用したい以下のスキーマオブジェクトがあるとします。
1"components":2 {3 "schemas":4 {5 "user":6 {7 "properties":8 { "id": { "type": "integer" }, "name": { "type": "string" } },9 },10 },11 }
1components:2 schemas:3 User:4 properties:5 id:6 type: integer7 name:8 type: string
そのオブジェクトを参照するには、レスポンスに $ref
と対応するパスを追加する必要があります。
1"responses":2 {3 "200":4 {5 "description": "The response",6 "schema": { "$ref": "#/components/schemas/user" },7 },8 }
1responses:2 "200":3 description: The response4 schema:5 $ref: "#/components/schemas/User"
$ref
の値は JSON Reference 記法を使用し、#
から始まる部分は JSON Pointer 記法を使用します。この記法により、参照したいターゲットファイルまたはファイル内の特定の箇所を指定できます。前の例では、#/components/schemas/User
は、現在のドキュメントのルートから解決が始まり、その後 components
、schemas
、User
の値が順次見つけられることを意味します。
$ref 構文
RFC3986 によると、$ref
文字列値 (JSON Reference) には、参照する JSON 値の場所を識別する URI を含める必要があります。文字列値が URI 構文規則に準拠しない場合、解決中にエラーが発生します。JSON Reference オブジェクト内の $ref
以外のメンバーは無視されます。特定のケースにおける JSON Reference の例については、以下のリストを確認してください。
- ローカル参照 –
$ref: '#/definitions/myElement'
#
は、現在のドキュメントのルートに移動し、次にdefinitions
とmyElement
要素を順次見つけることを意味します。 - リモート参照 –
$ref: 'document.json'
同じサーバーの同じ場所にあるドキュメント全体を使用します。- 同じフォルダーにあるドキュメントの要素 –
$ref: 'document.json#/myElement'
- 親フォルダーにあるドキュメントの要素 –
$ref: '../document.json#/myElement'
- 別のフォルダーにあるドキュメントの要素 –
$ref: '../another-folder/document.json#/myElement'
- 同じフォルダーにあるドキュメントの要素 –
- URL 参照 –
$ref: 'http://path/to/your/resource'
別のサーバーにあるドキュメント全体を使用します。- 別のサーバーに保存されているドキュメントの特定の要素 –
$ref: 'http://path/to/your/resource.json#/myElement'
- 同じプロトコルを使用する別のサーバー上のドキュメント (例: HTTP または HTTPS) –
$ref: '//anotherserver.com/files/example.json'
- 別のサーバーに保存されているドキュメントの特定の要素 –
注意: YAML で #/components/schemas/User
のようなローカル参照を使用する場合、値を引用符で囲んでください: '#/components/schemas/User'
。そうしないと、コメントとして扱われます。
エスケープ文字
/
および ~
は JSON Pointer の特殊文字であり、文字どおり使用する場合 (たとえばパス名で) はエスケープする必要があります。
文字 | エスケープ方法 |
---|---|
~ | ~0 |
/ | ~1 |
たとえば、パス /blogs/{blog_id}/new~posts
を参照するには、次のようにします。
1$ref: "#/paths/~1blogs~1{blog_id}~1new~0posts"
考慮事項
$ref が使用できる場所
$ref
が OpenAPI 仕様ファイル内のどこでも許可されているという誤解がよくあります。実際には、$ref
は OpenAPI 3.0 仕様が値が「参照」であると明示的に述べている場所でのみ許可されます。たとえば、$ref
は info
セクションや paths
の直下では使用できません。
1openapi: 3.0.42
3# Incorrect!4info:5 $ref: info.yaml6paths:7 $ref: paths.yaml
しかし、個々のパスを $ref
することは可能です。
1paths:2 /users:3 $ref: "../resources/users.yaml"4 /users/{userId}:5 $ref: "../resources/users-by-id.yaml"
$ref と兄弟要素
$ref
の兄弟要素はすべて無視されます。これは、$ref
がそれ自体と、そのレベルにあるすべてのものを、それが指す定義に置き換えることで機能するためです。次の例を考えてみましょう。
1components:2 schemas:3 Date:4 type: string5 format: date6
7 DateWithExample:8 $ref: "#/components/schemas/Date"9 description: Date schema extended with a `default` value... Or not?10 default: 2000-01-01
2番目のスキーマでは、description
と default
プロパティは無視されるため、このスキーマは参照された Date
スキーマとまったく同じになります。
お探しのものが見つかりませんでしたか? コミュニティに質問する
間違いを見つけましたか? お知らせください