JSON模式:"allof";带有"additionalProperties" [英] JSON schema : "allof" with "additionalProperties"

查看:352
本文介绍了JSON模式:"allof";带有"additionalProperties"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有遵循以下模式的模式(来自教程此处):

Suppose we have schema following schema (from tutorial here):

{
  "$schema": "http://json-schema.org/draft-04/schema#",

  "definitions": {
    "address": {
      "type": "object",
      "properties": {
        "street_address": { "type": "string" },
        "city":           { "type": "string" },
        "state":          { "type": "string" }
      },
      "required": ["street_address", "city", "state"]
    }
  },

  "type": "object",

  "properties": {
    "billing_address": { "$ref": "#/definitions/address" },
    "shipping_address": {
      "allOf": [
        { "$ref": "#/definitions/address" },
        { "properties":
          { "type": { "enum": [ "residential", "business" ] } },
          "required": ["type"]
        }
      ]
    } 

  }
}

这是有效的实例:

{
      "shipping_address": {
        "street_address": "1600 Pennsylvania Avenue NW",
        "city": "Washington",
        "state": "DC",
        "type": "business"
      }
}

我需要确保shipping_address的所有其他字段都无效.我知道为此存在additionalProperties,应将其设置为"false".但是,当我如下设置"additionalProprties":false时:

I need to ensure that any additional fields for shipping_address will be invalid. I know for this purpose exists additionalProperties which should be set to "false". But when I'm setting "additionalProprties":false as in the following:

"shipping_address": {
          "allOf": [
            { "$ref": "#/definitions/address" },
            { "properties":
              { "type": { "enum": [ "residential", "business" ] } },
              "required": ["type"]
            }
          ],
          "additionalProperties":false
        } 

我收到验证错误(在此处选中):

I get a validation error (checked here):

[ {
  "level" : "error",
  "schema" : {
    "loadingURI" : "#",
    "pointer" : "/properties/shipping_address"
  },
  "instance" : {
    "pointer" : "/shipping_address"
  },
  "domain" : "validation",
  "keyword" : "additionalProperties",
  "message" : "additional properties are not allowed",
  "unwanted" : [ "city", "state", "street_address", "type" ]
} ] 

问题是:我应该如何仅限制shipping_address部分的字段?预先感谢.

The question is: how should I to limit fields for the shipping_address part only? Thanks in advance.

推荐答案

[此处是v4验证规范草案的作者]

[author of the draft v4 validation spec here]

您偶然发现了JSON Schema中最常见的问题,即它根本无法如用户期望的那样进行继承.但同时,它也是其核心功能之一.

You have stumbled upon the most common problem in JSON Schema, that is, its fundamental inability to do inheritance as users expect; but at the same time it is one of its core features.

当您这样做:

"allOf": [ { "schema1": "here" }, { "schema2": "here" } ]

schema1schema2彼此不了解.他们会根据自己的情况进行评估.

schema1 and schema2 have no knowledge of one another; they are evaluated in their own context.

在您遇到很多人的情况下,您希望schema2知道schema1中定义的属性;但是事实并非如此,永远不会如此.

In your scenario, which many, many people encounter, you expect that properties defined in schema1 will be known to schema2; but this is not the case and will never be.

这个问题就是为什么我对v5草案提出了以下两个建议:

This problem is why I have made these two proposals for draft v5:

您的shipping_address模式将为:

{
    "merge": {
        "source": { "$ref": "#/definitions/address" },
        "with": {
            "properties": {
                "type": { "enum": [ "residential", "business" ] }
            }
        }
    }
}

以及在address中将strictProperties定义为true.

顺便说一句,我也是您所引用的网站的作者.

Incidentally, I am also the author of the website you are referring to.

现在,让我回溯到草案v3. v3草案确实定义了extends,其值可以是模式或模式数组.通过此关键字的定义,它意味着实例必须对当前架构中指定的所有架构有效.基本上,草案v4的allOf是草案v3的extends.

Now, let me backtrack to draft v3. Draft v3 did define extends, and its value was either of a schema or an array of schemas. By the definition of this keyword, it meant that the instance had to be valid against the current schema and all schemas specified in extends; basically, draft v4's allOf is draft v3's extends.

考虑一下(草稿v3):

Consider this (draft v3):

{
    "extends": { "type": "null" },
    "type": "string"
}

现在,那个:

{
    "allOf": [ { "type": "string" }, { "type": "null" } ]
}

它们是相同的.还是那个?

They are the same. Or maybe that?

{
    "anyOf": [ { "type": "string" }, { "type": "null" } ]
}

还是那个?

{
    "oneOf": [ { "type": "string" }, { "type": "null" } ]
}

总而言之,这意味着v3草案中的extends从未真正做到人们期望的那样.在草案v4中,明确定义了*Of关键字.

All in all, this means that extends in draft v3 never really did what people expected it to do. With draft v4, *Of keywords are clearly defined.

但是,到目前为止,您遇到的问题是最常见的问题.因此,我的提议将一劳永逸地消除这种误解!

But the problem you have is the most commonly encountered problem, by far. Hence my proposals which would quench this source of misunderstanding once and for all!

这篇关于JSON模式:"allof";带有"additionalProperties"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆