将必填字段应用于引用的JSON数据模式

时间:2019-07-25 09:23:21

标签: json reference jsonschema

我有以下尝试用JSON模式解决的用例。

我有一个通用的JSON数据架构,例如一个用户。这是user.schema.json文件的示例。

{
  "type": "object",
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1
    },
    "email": {
      "type": "string",
      "minLength": 1
    },
    "locale": {
      "type": "string",
      "minLength": 1
    },
    "active": {
      "type": "boolean",
      "default": true
    },
    "password": {
      "type": "string",
      "minLength": 8
    },
    "roles": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      }
    }
  }
}

现在我有2种不同的请求: -POST:添加用户 -补丁:更新用户数据。

在1种情况下,我可以发送带有3个必填字段的数据结构,而在打补丁的情况下,每个字段都是可选的。 所以我得到了发布请求文件:post-user.schema.json:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$ref": "user.schema.json",
  "required": [
    "name",
    "password",
    "email"
  ]
}

对于我的补丁(path-user.schema.json:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$ref": "user.schema.json"
}

现在我遇到的问题是我的POST模式也将用户标记为:

{
    "name": "NoPassword",
    "email": "nopassword@moba.nl",
    "roles": []
}

缺少一个有效的JSON模式的必填密码字段。

显然,这不是将必填字段分配给引用的数据结构的方法。我尝试使用google来搜索相关内容,例如: [如何将必填字段分配给引用的架构] 我试图从文档中获取此信息。

我没有运气。

我现在的问题是: 答:是否可以将必需字段分配给$ referenced json模式数据对象。 B.如果可能的话,该怎么做 C.如果这不可能,那么解决这个问题的好方法是什么。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

使用$ref会导致对象中的所有其他属性被忽略,因此您需要包装$ref的使用。

让我们看一下规格:

  

具有“ $ ref”属性的对象模式必须解释为
  “ $ ref”参考。 “ $ ref”属性的值必须是URI
  参考。根据当前URI基础进行解析,它标识了
  要使用的架构的URI。 “ $ ref”对象中的所有其他属性必须   被忽略。

https://tools.ietf.org/html/draft-handrews-json-schema-01#section-8.3

然后考虑您包含在问题中的架构:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$ref": "user.schema.json",
  "required": [
    "name",
    "password",
    "email"
  ]
}

通过阅读规范,您可以了解为什么required将被忽略。

最初$ref只是用于替换整个对象,而不能添加到该对象的条件。

您想要的是将多个架构应用于实例。为此,请使用allOf

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "allOf": [
    {
      "$ref": "user.schema.json"
    },
    {
      "required": [
        "name",
        "password",
        "email"
      ]
    }
  ]
}

我将此模式加载到一个演示中,供您在https://jsonschema.dev进行测试-尽管它尚不支持引用,所以我将其排除在外,但验证仍可以进行。

从草稿8开始,$ref会像您期望的那样运行,因为它成为应用程序关键字,而不是具有特殊行为的关键字,这意味着同一对象中的其他关键字将不需要被忽略。

>