JSON 架构相对引用解析
JSON Schema relative references resolution
我正在尝试定义一个有效的 JSON 架构,但我不确定当引用的组件位于子目录中时如何构造引用 ("$ref") 值。我已经(详细地)阅读了官方 JSON Schema 站点上的信息,并检查了来自各种 JSON Schema 解析器的测试数据,但是可用信息不清楚或不可用(或者,当然,我找了好几个小时都没找到)...
我需要的具体帮助是确认组件目录中文件的引用——引用组件目录中的文件——是否应该在参考与否。 (请注意,$id 不可用于提供基本 URI)。
换句话说,“message.schema.json”中的引用应该是:
- 选项 1:“components/key.schema.json”和“components/data.schema.json”,或者,
- 选项2:“key.schema.json”和“data.schema.json”(如下图)
在选项 1 中,“$ref”相对于父路径(“main.schema.json”),在选项 2 中它相对于当前路径(“message.schema.json”) ).
以下是提供进一步上下文的信息。
文件结构比较简单,如下图所示:
main.schema.json
- message.schema.json
- key.schema.json
- data.schema.json
文件内容如下所示...
主.schema.json:
{
"$id": "https://example.com/arrays.schema.json",
"description": "main.schema.json",
"type": "object",
"required": [ "messages" ],
"properties": {
"messages": {
"type": "array",
"items": { "$ref": "components/message.schema.json" }
}
}
}
上面的JSON架构引用了“components”目录(main.schema.json文件下的一个目录)中的文件。
message.schema.json:
{
"$id": "https://example.com/arrays.schema.json",
"description": "message.schema.json",
"type": "object",
"required": [ "message" ],
"properties": {
"message": {
"type": "object",
"required": [ "key", "data" ],
"properties": {
"key": {
"$ref": "key.schema.json"
},
"data": {
"$ref": "data.schema.json"
}
}
}
}
}
上面的 message.schema.json 引用了与 message.schema.json 文件位于 相同 目录中的以下组件:
键。schema.json:
{
"$id": "https://example.com/arrays.schema.json",
"description": "key.schema.json",
"type": "object",
"required": [ "key" ],
"properties": {
"key": {
"type": "string"
}
}
}
数据。schema.json:
{
"$id": "https://example.com/arrays.schema.json",
"description": "data.schema.json",
"type": "object",
"required": [ "data" ],
"properties": {
"data": {
"type": "object",
"required": [ "veggieName", "veggieLike" ],
"properties": {
"veggieName": {
"type": "string",
"description": "The name of the vegetable."
},
"veggieLike": {
"type": "boolean",
"description": "Do I like this vegetable?"
}
}
}
}
}
为什么您的所有架构都相同 $id
?许多实现会在这方面出错,或者导致它们在您加载具有相同标识符的较晚模式时“忘记”较早模式。
我不确定您是否认为此处使用了 description
关键字,但事实并非如此。重要的关键字是 $id
,它的值用作将来 URI 解析的基础,例如在 $ref
.
中找到的那些
根据您使用的特定实现,您需要确保 $id
关键字中的 URI 可正确解析(也就是说,如果您转到 URL“ https://example.com/message.schema.json" 它实际上会下载一些东西),或者您需要在开始评估之前手动将所有文件加载到实施中。规范不要求实现支持网络解析,但它们需要支持某种机制,以便在其规范标识符下预加载模式。
如果将这些值用作 $id
s(将 example.com 替换为更合适的主机):
- https://example.com/main.schema.json
- https://example.com/components/message.schema.json
- https://example.com/components/key.schema.json
- https://example.com/components/data.schema.json
..然后所有从 main 到其他文件的引用都可以通过 uri 引用进行:
- 从主文件到其他文件:
"$ref": "components/key.schema.json"
等
- 从其他文件到彼此:
"$ref": "key.schema.json"
等
- 从其他文件回到主文件:
"$ref": "../main.schema.json"
您当然也可以在所有 $ref
中使用完整的绝对 URI。
我正在尝试定义一个有效的 JSON 架构,但我不确定当引用的组件位于子目录中时如何构造引用 ("$ref") 值。我已经(详细地)阅读了官方 JSON Schema 站点上的信息,并检查了来自各种 JSON Schema 解析器的测试数据,但是可用信息不清楚或不可用(或者,当然,我找了好几个小时都没找到)...
我需要的具体帮助是确认组件目录中文件的引用——引用组件目录中的文件——是否应该在参考与否。 (请注意,$id 不可用于提供基本 URI)。
换句话说,“message.schema.json”中的引用应该是:
- 选项 1:“components/key.schema.json”和“components/data.schema.json”,或者,
- 选项2:“key.schema.json”和“data.schema.json”(如下图)
在选项 1 中,“$ref”相对于父路径(“main.schema.json”),在选项 2 中它相对于当前路径(“message.schema.json”) ).
以下是提供进一步上下文的信息。
文件结构比较简单,如下图所示:
main.schema.json
- message.schema.json
- key.schema.json
- data.schema.json
文件内容如下所示...
主.schema.json:
{
"$id": "https://example.com/arrays.schema.json",
"description": "main.schema.json",
"type": "object",
"required": [ "messages" ],
"properties": {
"messages": {
"type": "array",
"items": { "$ref": "components/message.schema.json" }
}
}
}
上面的JSON架构引用了“components”目录(main.schema.json文件下的一个目录)中的文件。
message.schema.json:
{
"$id": "https://example.com/arrays.schema.json",
"description": "message.schema.json",
"type": "object",
"required": [ "message" ],
"properties": {
"message": {
"type": "object",
"required": [ "key", "data" ],
"properties": {
"key": {
"$ref": "key.schema.json"
},
"data": {
"$ref": "data.schema.json"
}
}
}
}
}
上面的 message.schema.json 引用了与 message.schema.json 文件位于 相同 目录中的以下组件:
键。schema.json:
{
"$id": "https://example.com/arrays.schema.json",
"description": "key.schema.json",
"type": "object",
"required": [ "key" ],
"properties": {
"key": {
"type": "string"
}
}
}
数据。schema.json:
{
"$id": "https://example.com/arrays.schema.json",
"description": "data.schema.json",
"type": "object",
"required": [ "data" ],
"properties": {
"data": {
"type": "object",
"required": [ "veggieName", "veggieLike" ],
"properties": {
"veggieName": {
"type": "string",
"description": "The name of the vegetable."
},
"veggieLike": {
"type": "boolean",
"description": "Do I like this vegetable?"
}
}
}
}
}
为什么您的所有架构都相同 $id
?许多实现会在这方面出错,或者导致它们在您加载具有相同标识符的较晚模式时“忘记”较早模式。
我不确定您是否认为此处使用了 description
关键字,但事实并非如此。重要的关键字是 $id
,它的值用作将来 URI 解析的基础,例如在 $ref
.
根据您使用的特定实现,您需要确保 $id
关键字中的 URI 可正确解析(也就是说,如果您转到 URL“ https://example.com/message.schema.json" 它实际上会下载一些东西),或者您需要在开始评估之前手动将所有文件加载到实施中。规范不要求实现支持网络解析,但它们需要支持某种机制,以便在其规范标识符下预加载模式。
如果将这些值用作 $id
s(将 example.com 替换为更合适的主机):
- https://example.com/main.schema.json
- https://example.com/components/message.schema.json
- https://example.com/components/key.schema.json
- https://example.com/components/data.schema.json
..然后所有从 main 到其他文件的引用都可以通过 uri 引用进行:
- 从主文件到其他文件:
"$ref": "components/key.schema.json"
等 - 从其他文件到彼此:
"$ref": "key.schema.json"
等 - 从其他文件回到主文件:
"$ref": "../main.schema.json"
您当然也可以在所有 $ref
中使用完整的绝对 URI。