コンテンツにスキップ

$ref の使用

API をドキュメント化する際、複数の API リソースで利用する共通の機能があることがよくあります。その場合、そのような要素の断片を作成し、必要なときに何度も使用することができます。OpenAPI 3.0 では、任意の場所(同じサーバー、GitHub、SwaggerHubなど)にホストされている定義を参照できます。定義を参照するには、$ref キーワードを使用します。

1
$ref: "reference to definition"

たとえば、レスポンス内で使用したい以下のスキーマオブジェクトがあるとします。

JSON 例
1
"components":
2
{
3
"schemas":
4
{
5
"user":
6
{
7
"properties":
8
{ "id": { "type": "integer" }, "name": { "type": "string" } },
9
},
10
},
11
}
YAML 例
1
components:
2
schemas:
3
User:
4
properties:
5
id:
6
type: integer
7
name:
8
type: string

そのオブジェクトを参照するには、レスポンスに $ref と対応するパスを追加する必要があります。

JSON 例
1
"responses":
2
{
3
"200":
4
{
5
"description": "The response",
6
"schema": { "$ref": "#/components/schemas/user" },
7
},
8
}
YAML 例
1
responses:
2
"200":
3
description: The response
4
schema:
5
$ref: "#/components/schemas/User"

$ref の値は JSON Reference 記法を使用し、# から始まる部分は JSON Pointer 記法を使用します。この記法により、参照したいターゲットファイルまたはファイル内の特定の箇所を指定できます。前の例では、#/components/schemas/User は、現在のドキュメントのルートから解決が始まり、その後 componentsschemasUser の値が順次見つけられることを意味します。

$ref 構文

RFC3986 によると、$ref 文字列値 (JSON Reference) には、参照する JSON 値の場所を識別する URI を含める必要があります。文字列値が URI 構文規則に準拠しない場合、解決中にエラーが発生します。JSON Reference オブジェクト内の $ref 以外のメンバーは無視されます。特定のケースにおける JSON Reference の例については、以下のリストを確認してください。

  • ローカル参照$ref: '#/definitions/myElement' # は、現在のドキュメントのルートに移動し、次に definitionsmyElement 要素を順次見つけることを意味します。
  • リモート参照$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 仕様ファイル内のどこでも許可されているという誤解がよくあります。実際には、$refOpenAPI 3.0 仕様が値が「参照」であると明示的に述べている場所でのみ許可されます。たとえば、$refinfo セクションや paths の直下では使用できません。

1
openapi: 3.0.4
2
3
# Incorrect!
4
info:
5
$ref: info.yaml
6
paths:
7
$ref: paths.yaml

しかし、個々のパスを $ref することは可能です。

1
paths:
2
/users:
3
$ref: "../resources/users.yaml"
4
/users/{userId}:
5
$ref: "../resources/users-by-id.yaml"

$ref と兄弟要素

$ref の兄弟要素はすべて無視されます。これは、$ref がそれ自体と、そのレベルにあるすべてのものを、それが指す定義に置き換えることで機能するためです。次の例を考えてみましょう。

1
components:
2
schemas:
3
Date:
4
type: string
5
format: date
6
7
DateWithExample:
8
$ref: "#/components/schemas/Date"
9
description: Date schema extended with a `default` value... Or not?
10
default: 2000-01-01

2番目のスキーマでは、descriptiondefault プロパティは無視されるため、このスキーマは参照された Date スキーマとまったく同じになります。

お探しのものが見つかりませんでしたか? コミュニティに質問する
間違いを見つけましたか? お知らせください