programing

JSON 스키마: "all of"과 "additionalProperties"

sourcejob 2023. 3. 20. 23:10
반응형

JSON 스키마: "all of"과 "additionalProperties"

다음 스키마가 있다고 가정합니다(여기 튜토리얼 참조).

{
  "$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다음과 같습니다.

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

검증 에러가 표시된다(여기에 체크 마크가 붙어 있다.

[ {
  "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부품만?잘 부탁드립니다.

[v4 검증 사양 초안 작성자는 이쪽]

JSON Schema에서 가장 일반적인 문제, 즉 사용자가 기대하는 대로 상속을 수행할 수 없는 근본적인 문제에 부딪혔지만 동시에 JSON Schema의 핵심 기능 중 하나입니다.

실행 시:

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

schema1그리고.schema2서로에 대한 지식이 없다; 그들은 그들 자신의 맥락에서 평가된다.

많은 사람들이 접하는 시나리오에서는 다음과 같은 속성이 정의되어 있습니다.schema1에게 알려질 것이다schema2그러나 이것은 사실이 아니며 앞으로도 그럴 것이다.

이 문제로 인해 초안 v5에 대해 다음 두 가지 제안을 했습니다.

스키마:shipping_address다음과 같습니다.

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

정의와 함께strictProperties로.trueaddress.


덧붙여서, 저는 당신이 언급하고 있는 웹사이트의 저자이기도 합니다.

이제 초안 v3로 돌아가 보겠습니다.초안 v3는 정의되어 있습니다.extends그 값은 스키마 또는 스키마 배열 중 하나였습니다.이 키워드의 정의에 따르면 인스턴스는 현재 스키마 및 에서 지정된 모든 스키마에 대해 유효해야 합니다.extends; 기본적으로는 v4 드래프트allOf드래프트 v3의extends.

다음 사항을 고려하십시오(초안 v3).

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

그리고 지금, 그것은:

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

둘 다 똑같아요.아니면 그거?

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

아니면 그거?

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

한마디로 말해서extends초안 v3에서는 사람들이 기대했던 대로 되지 않았습니다.드래프트 v4에서는*Of키워드는 명확하게 정의되어 있습니다.

하지만 당신이 안고 있는 문제는 단연코 가장 흔한 문제입니다.그러므로 나의 제안은 이 오해를 완전히 해소할 것이다!

additionalProperties에 의해 설명되지 않은 모든 재산에 적용된다.properties또는patternProperties즉시 스키마로 설정합니다.

즉, 다음과 같은 경우:

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

additionalProperties형제 수준이 없기 때문에 모든 속성에 적용됩니다.propertiesentry : 내부allOf을 사용하다

할 수 있는 은, 「이행」의 「」properties위로 합니다.1 " Import " stub " 。

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

, ,,additionalProperties원하는 속성에는 적용되지 않습니다.

다음은 Yves-M's Solution의 간단한 버전입니다.

{
  "$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"
          ]
        },
        "street_address": {},
        "city": {},
        "state": {}
      },
      "required": [
        "type"
      ],
      "additionalProperties": false
    }
  }
}

됩니다.address한 스키마만 합니다.type의 속성shipping_address.

additionalProperties에서는 즉시 형제 수준의 속성만 고려됩니다.아마도 여기에는 이유가 있을 것이다.하지만 이것이 우리가 상속받은 속성을 반복해야 하는 이유입니다.

여기서는 상속된 속성을 빈 개체 구문을 사용하여 단순 형식으로 반복합니다.즉, 이러한 이름을 가진 속성은 포함된 값의 종류에 관계없이 유효합니다. 할 수 .allOf에 기타 을하기 위한 address스키마

정의 수준에서 additionalProperties=false를 설정하지 않음

모든 게 잘 될 거야

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

    "type": "object",
    "properties": {

        "billing_address": {
            "allOf": [
                { "$ref": "#/definitions/address" }
            ],
            "properties": {
                "street_address": {},
                "city": {},
                "state": {}                 
            },          
            "additionalProperties": false
            "required": ["street_address", "city", "state"] 
        },

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

    }
}

각각자 eachbilling_address ★★★★★★★★★★★★★★★★★」shipping_address에서는 필요한 속성을 지정해야 합니다.

에는 '하다'가 있어서는 안 ."additionalProperties": false그의 재산을 다른 재산과 결합하고 싶다면요

스펙 2019-09 이상의 유효한 답변을 게재한 사람이 없기 때문에 Andreas H.의 코멘트를 놓칠 뻔했습니다.

{
  "$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"]
      // additionalProperties: false    // <-- Remove completely if present 
    }
  },

  "type": "object",

  "properties": {
    "billing_address": { "$ref": "#/definitions/address" },
    "shipping_address": {
      "unevaluatedProperties": false,   // <-- Add to same level as allOf as false
      "allOf": [
        { "$ref": "#/definitions/address" },
        { "properties":
          { "type": { "enum": [ "residential", "business" ] } },
          "required": ["type"]
        }
      ]
    } 
  }
}

저자는 여기서 꽤 명확하고 간결한 설명을 찾을 수 있다.

언급URL : https://stackoverflow.com/questions/22689900/json-schema-allof-with-additionalproperties

반응형