JSON 架构相对引用解析

JSON Schema relative references resolution

我正在尝试定义一个有效的 JSON 架构,但我不确定当引用的组件位于子目录中时如何构造引用 ("$ref") 值。我已经(详细地)阅读了官方 JSON Schema 站点上的信息,并检查了来自各种 JSON Schema 解析器的测试数据,但是可用信息不清楚或不可用(或者,当然,我找了好几个小时都没找到)...

我需要的具体帮助是确认组件目录中文件的引用——引用组件目录中的文件——是否应该在参考与否。 (请注意,$id 不可用于提供基本 URI)。

换句话说,“message.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" 它实际上会下载一些东西),或者您需要在开始评估之前手动将所有文件加载到实施中。规范不要求实现支持网络解析,但它们需要支持某种机制,以便在其规范标识符下预加载模式。

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

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

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

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