【问题标题】:JSON Schema relative references resolutionJSON Schema 相对引用解析
【发布时间】:2021-12-19 02:06:04
【问题描述】:

我正在尝试定义一个有效的 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

文件内容如下图...

main.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 Schema 引用了“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 文件相同目录下的以下组件:

key.schema.json:

{
  "$id": "https://example.com/arrays.schema.json",
  "description": "key.schema.json",
  "type": "object",
  "required": [ "key" ],
  "properties": {
    "key": {
      "type": "string"
    }
  }
}

data.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?"
        }
      }
    }
  }
}

【问题讨论】:

标签: jsonschema json-schema-validator jsonschema2pojo python-jsonschema njsonschema


【解决方案1】:

为什么所有架构都具有相同的$id?许多实现会在这方面出错,或者导致它们在您加载具有相同标识符的后续架构时“忘记”早期架构。

我不确定您是否认为这里使用了 description 关键字,但事实并非如此。重要的关键字是$id,它的值用作未来URI 解析的基础,例如$ref 中的那些。

根据您使用的特定实现,您需要确保 $id 关键字中的 URI 可以正确解析(也就是说,如果您转到 URL“https://example.com/ message.schema.json”它实际上会下载一些东西),或者您需要在开始评估之前手动将所有文件加载到实现中。规范并不要求实现支持网络解析,但它们需要支持某种机制,以便在其规范标识符下预加载模式。

如果您将这些值用作$ids(将 example.com 替换为更合适的主机):

..那么从 main 到其他文件的所有引用都可以通过 uri 引用进行:

  • 从主文件到其他文件:"$ref": "components/key.schema.json"
  • 从其他文件到彼此:"$ref": "key.schema.json"
  • 从其他文件回到主文件:"$ref": "../main.schema.json"

当然,您也可以在所有 $refs 中使用完整的绝对 URI。

【讨论】:

  • 反响很好。快速跟进问题:如果任何文档中都不存在“$id”标签会发生什么变化? “components”目录中的“message.schema.json”如何在“components”目录中引用“key.schema.json”? “message.schema.json”会使用(a)“$ref”:“key.schema.json”还是(b)“$ref”:“components/key.schema.json”? (如果答案很长/很复杂,请告诉我,我可以提交一个新问题)
  • $id 如果要引用它,则在模式中是必需的。某些实现可能允许您添加架构并告诉它$id 应该 是什么,但不要假设所有实现都允许它。
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 2020-03-14
  • 2019-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
相关资源
最近更新 更多