jmckie
jmckie

Reputation: 259

JSON Schema Validation - required fields depending on boolean value

I have looked at many other posts, but can't find a solution to my problem.

I'm trying to validate the following scenario through a json schema:

If isRetired = false then retirementAge, salary and salaryFreq are additionally required.

I have tried the below in addition to a oneOf with 2 schemas to include all the required fields for isRetired = true/false but that never worked either.

Any suggestions would be greatly appreciated.

Thanks in advance!

{
    "definitions": {},
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "additionalProperties": false,
    "required": ["input"],
    "properties": {
      "input": {
        "$id": "#root/input",
        "title": "Input",
        "type": "object",
        "required": ["persons"],
        "properties": {
          "persons": {
            "$id": "#root/input/persons",
            "title": "Persons",
            "type": "array",
            "default": [],
            "minItems": 1,
            "maxItems": 2,
            "items": {
              "$id": "#root/input/persons/items",
              "title": "Items",
              "type": "object",
              "required": [
                "gender",
                "age",
                "isRetired",
                "superConcContPercentage",
                "totalSuper",
                "riskGrowthPercentage",
                "includeAgePension"
              ],
              "properties": {
                "firstName": {
                  "$id": "#root/input/persons/items/firstName",
                  "title": "Firstname",
                  "type": "string",
                  "default": "",
                  "examples": ["Joe"],
                  "pattern": "^.*$"
                },
                "lastName": {
                  "$id": "#root/input/persons/items/lastName",
                  "title": "Lastname",
                  "type": "string",
                  "default": "",
                  "examples": ["Bloggs"],
                  "pattern": "^.*$"
                },
                "gender": {
                  "$id": "#root/input/persons/items/gender",
                  "title": "Gender",
                  "type": "string",
                  "default": "",
                  "examples": ["male"],
                  "pattern": "^.*$"
                },
                "age": {
                  "$id": "#root/input/persons/items/age",
                  "title": "Age",
                  "type": "integer",
                  "examples": [27],
                  "default": 0,
                  "minimum": 18,
                  "maximum": 110
                },
                "isRetired": {
                  "$id": "#root/input/persons/items/isRetired",
                  "title": "Isretired",
                  "type": "boolean",
                  "examples": [false],
                  "default": true
                },
                "retirementAge": {
                  "$id": "#root/input/persons/items/retirementAge",
                  "title": "Retirementage",
                  "type": "integer",
                  "examples": [70],
                  "default": 0,
                  "minimum": 19,
                  "maximum": 110
                },
                "salary": {
                  "$id": "#root/input/persons/items/salary",
                  "title": "Salary",
                  "type": "integer",
                  "examples": [100000],
                  "default": 0,
                  "minimum": 0
                },
                "salaryFreq": {
                  "$id": "#root/input/persons/items/salaryFreq",
                  "title": "Salaryfreq",
                  "type": "integer",
                  "examples": [12],
                  "default": 0
                },
                "superConcContPercentage": {
                  "$id": "#root/input/persons/items/superConcContPercentage",
                  "title": "Superconccontpercentage",
                  "type": "integer",
                  "examples": [0],
                  "default": 0,
                  "minimum": 0,
                  "maximum": 100
                },
                "totalSuper": {
                  "$id": "#root/input/persons/items/totalSuper",
                  "title": "Totalsuper",
                  "type": "integer",
                  "examples": [10000],
                  "default": 0,
                  "minimum": 0
                },
                "riskGrowthPercentage": {
                  "$id": "#root/input/persons/items/riskGrowthPercentage",
                  "title": "Riskgrowthpercentage",
                  "type": "integer",
                  "examples": [50],
                  "default": 0,
                  "minimum": 0,
                  "maximum": 100
                },
                "includeAgePension": {
                  "$id": "#root/input/persons/items/includeAgePension",
                  "title": "Includeagepension",
                  "type": "boolean",
                  "examples": [false],
                  "default": true
                }
              }
            },
            "if": {
              "properties": {
                "isRetired": {
                  "const": false
                }
              }
            },
            "then": {
              "required": [
                "retirementAge",
                "salary",
                "salaryFreq"
              ]
            },
            "else": {
              "required": []
            }
          }
        }
      }
    }
  }

Upvotes: 1

Views: 1733

Answers (2)

jmckie
jmckie

Reputation: 259

I ended up with the below to satisfy the use case:

"if": {
  "properties": {
    "isRetired": {
      "const": false
    }
  }
},
"then": {
  "properties": {
    "salary": {
      "$id": "#root/input/persons/items/salary",
      "title": "Salary",
      "type": "integer",
      "examples": [100000],
      "default": 0,
      "minimum": 0
    },
    "salaryFreq": {
      "$id": "#root/input/persons/items/salaryFreq",
      "title": "Salaryfreq",
      "type": "integer",
      "examples": [12],
      "default": 0
    }
  },
  "required": ["salary", "salaryFreq"]
}

Upvotes: 0

Benjamin Peinhardt
Benjamin Peinhardt

Reputation: 486

I discovered your question while trying to figure this exact use case out for myself. Here is what I came up with:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "trigger": { "type": "boolean" },
        "dependentProp": { "type": "string" }
    },
    "if": {
        "properties": {
            "trigger": {
              "type": "boolean",
              "enum": [false]
            }
        }
    },
    "then": { "required": ["dependentProp"] }
}

There might be a cleaner way to do it but it worked for me so I'm going with it and moving on haha.

Upvotes: 2

Related Questions