0

My JSON payload contains two attributes home_number, home_name and at least one attribute always be required. Apart from that those attributes have the following additional constraints.

home_number: type: string, Max length: 4

home_name: type: string, Max length: 50

JSON schema should throw an error if both attributes did not meet requirements.

eg:

valid JSON

{
    "home_number": "1234", // valid
}

valid JSON

{
    "home_number": null, // invalid
    "home_name": "test_home_name" // valid
}

invalid JSON

{
    "home_number": "12345", // invalid
    "home_name": null // invalid
}

I tried the following JSON schema with draft-07 version using if, then keywords.

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "address": {
            "$ref": "#/definitions/address",
            "properties": {
                "house_number": {
                    "$ref": "#/definitions/address/house_number"
                },
                "house_name": {
                    "$ref": "#/definitions/address/house_name"
                },
                "post_code": {
                    "$ref": "#/definitions/address/postcode"
                }
            }
        }
    },
    "required": [
        "address"
    ],
    "definitions": {
        "address": {
            "type": "object",
            "properties": {
                "postcode": {
                    "type": "string",
                    "maxLength": 6
                }
            },
            "anyOf": [
                {
                    "required": [
                        "house_number"
                    ]
                },
                {
                    "required": [
                        "house_name"
                    ]
                }
            ],
            "if": {
                "properties": {
                    "house_name": {
                        "not": {
                            "type": "string",
                            "maxLength": 50
                        }
                    }
                }
            },
            "then": {
                "properties": {
                    "house_number": {
                        "type": "string",
                        "maxLength": 4
                    }
                }
            },
            "required": [
                "postcode"
            ]
        }
    }
}

My question is is there any other/better approach to achieve this using draft-04 version without using draft-07 if then keywords?

Community
  • 1
  • 1
lahiruk
  • 433
  • 3
  • 13
  • 1
    `if`/`then`/`else` is really just a fancy `oneOf`. You can most certainly use that instead. – gregsdennis Jul 02 '19 at 12:21
  • Possible duplicate of [JSON Schema - conditional validation](https://stackoverflow.com/questions/56424330/json-schema-conditional-validation) – Relequestual Jul 02 '19 at 12:26
  • Possible duplicate of [jsonSchema attribute conditionally required](https://stackoverflow.com/questions/38717933/jsonschema-attribute-conditionally-required) – Jason Desrosiers Jul 07 '19 at 00:48

1 Answers1

0

As pointed out in comments, this possibly has been asked multiple times.

A usage of logical operators does the trick, schema and json examples below. I can't say if it's better or not, it just groups anything within "anyOf" (and the requirement of postcode you can add whenever you need to, and you can structure references to full "properties" insides as you wish etc. etc.). Or you can put it as strict XOR "oneOf" (also as mentioned in comments) and make sure address->properties definition for each case is shaped as you need it.

Please read (linking to my own answer from past is not classy, but it may lead you to further reading): JSON Schema conditional: require and not require

A simplified schema and examples for your question (as I understood it):

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties" : {
    "address": {
      "type" : "object",
      "anyOf" : [
        { 
          "properties" : {
            "house_number" : {
              "type":"string",
              "maxLength": 4
            },
          },
          "required":["house_number"]
        },
        { 
          properties : {
            "house_name" : {
              "type" : "string",
                "maxLength" : 50
            }
          },
          "required":["house_name"]
        }
      ]
    }
  },
  required: ["address"],
  examples : [
    {
      baddress: {
      }
    },
    {
      address: {
        "house_number":"1234",
        "house_name" : null
      }
    },
    {
      address: {
        "house_number":null,
        "house_name" : null
      }
    },
    {
      address: {
        "house_number":null,
        "house_name" : "some name"
      }
    },
    {
      address: {
        "house_number": "12345",
        "house_name" : "some afafafasagagagffgfsagragsgasgasssssssfdgsdfgsdfgdsgsdfgsdgsdfgdfsgsdfgs name"
      }
    },
  ]
}
PsychoFish
  • 1,541
  • 12
  • 11