1
votes

I have the following use case with a JSON schema. I have a metadata object of a setting. In our case a setting can be of type string/real/integer/boolean.

In this object I have 4 fields: default/minimum/maximum each define a property of the setting. Now what I want to achieve is that when the type of de default value is an integer, also the minimum/maximum values are integers.

The schema I have come up with so far:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "definitions": {
    "setting-value": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "number"
        },
        {
          "type": "boolean"
        }
      ]
    },
    "setting-meta": {
      "type": "object",
      "required": [
        "name",
        "type",
        "default"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "type": {
          "type": "string",
          "enum": [
            "Real",
            "Integer",
            "Boolean",
            "String"
          ]
        },
        "minimum": {
          "$ref": "#/definitions/setting-value"
        },
        "maximum": {
          "$ref": "#/definitions/setting-value"
        },
        "default": {
          "$ref": "#/definitions/setting-value"
        },
        "value": {
          "$ref": "#/definitions/setting-value"
        }
      }
    }
  }
}

Here it is possible for the #/definitions/setting-meta to have support for the different types. However it does not define that if for example the value of TYPE is equal to Real/Integer that the types of minimum/maximum/default/value should all be of type number.

I would use these definitions as follows

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$ref": "schema-definition-above.json#/definitions/setting-meta"
}

According the the current schema, all examples below are VALID, however they should be valid/invalid as suggested:

Valid JSon object:

{
    "name": "Enabled",
    "type": "Boolean",
    "minimum": false,
    "maximum": true,
    "default": true,
    "value": true
}

Invalid json object, minimum/maximum/default don't have the same type:

{
    "name": "Enabled",
    "type": "Boolean",
    "minimum": false,
    "maximum": 1,
    "default": "value",
    "value": true
}

Invalid json object: type, does not match the actual type of the values

{
    "name": "Enabled",
    "unit": "enabled/disabled",
    "configId": "Accumulator",
    "displayName": "Enable or disable this machine",
    "type": "Integer",
    "minimum": false,
    "maximum": true,
    "default": true,
    "value": true
}

My question: Is it possible to put these kinds of dependencies into a JSON schema? The only kind of dependency I have foudn so far is with property dependencies indicating that if one property is set, another should also be set.

Any help would be much appreciated.

EDIT: Extended that use case with some JSON objects that should be validated or invalidated with the referenced schema.

1
Currently your schema only has definitions. Could you modify it to have some validation constraints please? Then I can help. I can help faster if you also provide a few examples of what you would like to be valid and invalidRelequestual
Hello Relequestual, Thank you for your reply. I added some examples as you suggested, hopefully this makes the issue more clear.Jan Jaap

1 Answers

1
votes

In order to do conditional validation where you have a known set of possible conditions, you should use the if/then/else keywords, in combination with with allOf.

In this schema, the first schema in allOf defines your general structure and overall requirements. The second schema applies the then constraint if the if schema validates successfully.

You would need to replicate the second schema for each condition that you have.

You can see this schema working at https://jsonschema.dev (link is preloaded with the below schema and sample data)

(The use of patternProperties is just a space saver. You could define each property individually.)

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "allOf": [
    {
      "properties": {
        "type": {
          "enum": [
            "Real",
            "Integer",
            "Boolean",
            "String"
          ]
        }
      },
      "required": [
        "type",
        "default",
        "name"
      ]
    },
    {
      "if": {
        "properties": {
          "type": {
            "const": "String"
          }
        }
      },
      "then": {
        "patternProperties": {
          "^(minimum|maximum|default|value)$": {
            "type": [
              "string"
            ]
          }
        }
      }
    }
  ]
}