是否可以创建有时可为空有时不为空的模式引用?

Is it possible to create schema references that are sometimes nullable and sometimes not?

我有一个重复使用对象类型的模式,我想将该类型提取到 $defs 中。但是,有时我需要它可以为空,有时则不需要。有什么好的方法可以实现吗?

包含所有重复项的示例模式:

{
  "type": "object",
  "properties": {
    "foo": {
      "type: "object",
      "properties: {
        "a": { "type": "string" },
        "b": { "type": ["string", "null"] },
        "c": { "type": ["string", "null"] }
      },
      "required": ["a"],
      "additionalProperties": false
    },
    "bar": {
      "type: "object",
      "properties: {
        "a": { "type": "string" },
        "b": { "type": ["string", "null"] },
        "c": { "type": ["string", "null"] }
      },
      "required": ["a"],
      "additionalProperties": false
    },
    "baz": {
      "type: ["object", "null"],
      "properties: {
        "a": { "type": "string" },
        "b": { "type": ["string", "null"] },
        "c": { "type": ["string", "null"] }
      },
      "required": ["a"],
      "additionalProperties": false
    }
  }
}

我可以 几乎 一路走来

{
  "type": "object",
  "properties": {
    "foo": { "$ref": "#/$defs/abc" },
    "bar": { "$ref": "#/$defs/abc" },
    "baz": { "$ref": "#/$defs/abc" }
  },
  "$defs": {
    "abc": {
      "type: "object",
      "properties: {
        "a": { "type": "string" },
        "b": { "type": ["string", "null"] },
        "c": { "type": ["string", "null"] }
      },
      "required": ["a"],
      "additionalProperties": false
    }
  }
}

但是,现在 baz 不可为空。如何实现属性定义等的最大可重用性,但具有可变的可空性?

空值在 JSON 中很奇怪,所以这里有点歧义。在大多数语言中,null 表示那里什么都没有。在 JSON 中,等价于“未定义”。如果某个值不存在于 JSON 中,则该值未定义。 JSON 中的 Null 是一个不同的概念,其中值存在且类型为“null”。 “null”类型由单一值 null 组成,不等同于 undefined.

因此,当您谈论可空性时,我假设您指的是“空”或未定义,因为您的架构就是这样编写的。如果您有选择,我建议您不要在 JSON 中使用 null,而是忽略没有价值的值。


JSON Schema 无法移除约束,因此您必须将定义定义得更精简一些,以便于组合。 "type": ["object", "null"]"anyOf: [{ "type": "object" }, { "type": "null" }] 的糖分。一旦你分解它,你最终会得到一个足够小的单元来促进你需要的组合。

{
  "type": "object",
  "properties": {
    "foo": { "$ref": "#/$defs/abc" },
    "bar": { "$ref": "#/$defs/abc" },
    "baz": {
      "anyOf": [
        { "$ref": "#/$defs/abc" },
        { "type": "null" }
      ]
    }
  },

  "$defs": {
    "abc": {
      "type: "object",
      "properties: {
        "a": { "type": "string" },
        "b": { "type": ["string", "null"] },
        "c": { "type": ["string", "null"] }
      },
      "required": ["a"],
      "additionalProperties": false
    }
  }
}