将必填字段应用于引用的 JSON 数据架构

Apply required field to referenced JSON data schema

我尝试使用 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
      }
    }
  }
}

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

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

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

还有我的补丁(路径-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 来查看我可以使用以下搜索找到关于此主题的内容: [如何将必填字段分配给引用的架构] 我试图从文档中获取此信息。

我运气不好

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

非常感谢任何帮助。

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

的使用

让我们看一下规范:

An object schema with a "$ref" property MUST be interpreted as a
"$ref" reference. The value of the "$ref" property MUST be a URI
Reference. Resolved against the current URI base, it identifies the
URI of a schema to use. All other properties in a "$ref" object MUST be ignored.

https://datatracker.ietf.org/doc/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 进行测试 - 尽管它尚不支持引用,因此我嵌入了引用,但验证将以相同的方式工作。

从 draft-8 开始,$ref 将按照您的预期运行,因为它成为一个应用程序关键字而不是具有特殊行为的关键字,这意味着不需要忽略同一对象中的其他关键字。