跳到内容

使用 $ref

在文档化 API 时,通常会有一些您在多个 API 资源中使用的功能。在这种情况下,您可以为这些元素创建代码片段,以便在需要时多次使用它们。借助 OpenAPI 3.0,您可以引用托管在任何位置的定义。它可以是同一服务器,也可以是另一个服务器——例如,GitHub、SwaggerHub 等。要引用定义,请使用 $ref 关键字

1
$ref: "reference to definition"

例如,假设您有以下 schema 对象,您希望在响应中使用它

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) 应该包含一个 URI,该 URI 标识您正在引用的 JSON 值的位置。如果字符串值不符合 URI 语法规则,则在解析期间会导致错误。JSON Reference 对象中除 $ref 之外的任何成员都将被忽略。请查看此列表以了解特定情况下 JSON 引用的示例值

  • 本地引用$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 规范文件的任何地方使用。实际上,$ref 仅允许在 OpenAPI 3.0 规范明确指出该值可以是 *引用* 的位置使用。例如,$ref 不能用于 info 部分和 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

在第二个 schema 中,descriptiondefault 属性被忽略,因此此 schema 最终与引用的 Date schema 完全相同。

没有找到您要找的内容?咨询社区
发现错误?告知我们

© . All rights reserved.