是否可以使用allOf(如果是,则多个)和$ ref创建JSON模式?

时间:2019-04-09 16:57:14

标签: json schema jsonschema json-schema-validator

我正在尝试创建一个复杂的架构,该架构将检查属性的值,然后根据该属性的值进行验证。我想知道是否可以在同一模式中使用$ ref和allOf,如果可以,如何?我在使它起作用时遇到了一些麻烦。请注意,我正在使用AJV。请在下面查看我的代码

{ 
  "$ref": "#/definitions/Welcome",
  "definitions": {
    "Welcome": {
      "properties": {
        "auth": {
          "type": "string",
          "enum": ["oauth1","oauth2"]
        },
        "environment": {
          "$ref": "#/definitions/Environment"
        }
      }
    },
    "Environment": {
      "properties": {
        "dev": {
          "type": "object"
        }
      }
    },
    "Oauth1": {
      "type": "object",
      "properties": {
        "temporary_credentials": {
          "type": "string"
        }
      }
    },
    "Oauth2": {
      "type": "object",
      "properties": {
        "auth_url": {
          "type": "string"
        }
      }
    }
  },
  "allOf": [
    {
      "if": {
        "auth": {
          "const": "oauth1"
        }
      },
      "then": {
        "environment": {
          "dev": {
            "$ref": "#/definitions/Oauth1
          }
        }
      }
    },
    {
      "if": {
        "auth": {
          "const": "oauth2"
        }
      },
      "then": {
        "environment": {
          "dev": {
            "$ref": "#/definitions/Oauth2
          }
        }
      }
    }
  ]
}

要针对 this 模式进行验证的示例json输入将是这样的

{
  "auth": "oauth1",
  "environment": {
    "dev": {
      "temporary_credentials": "xyzzy"
    }
  }
}

我觉得我的“ then”语句或allOf的位置可能有错误。我会收到类似“ $ ref:在路径“#”的模式中忽略的关键字”这样的错误。

1 个答案:

答案 0 :(得分:1)

在包含draft7以及更高版本的模式版本中,一旦使用"$ref",该模式级别的所有其他关键字都将被忽略。这就是错误告诉您的内容:因为您使用了$ref,所以其他关键字将被忽略。

如果您只想在根级别使用$ref,诀窍是将其包装在"allOf"中。

但是,由于您已经在根级别拥有allOf,因此您只需将$ref添加为allOf的另一个分支即可使用。

这看起来像:

"allOf": [
{
  "$ref": "#/definitions/Welcome",
},
{
  "if": {
    "auth": {
      "const": "oauth1"
    }
    etc.

注意:在发布的架构中,您有两个未闭合的字符串"#/definitions/Oauth1"#/definitions/Oauth2。如果您在实际架构中使用了该格式,那么它将是无效的JSON。