Home > front end >  Why my use of JSON Schema "allOf" not validating?
Why my use of JSON Schema "allOf" not validating?

Time:06-08

I am trying to apply some constraint to be json input through json schema validation.
Consider the below example where the metric enum value determines the minimum value of percent. In case of metric enum is "METRIC2", the minimum acceptable percent should be more than 2. Otherwise, percent can be anywhere from 0 to 100. I am following documentation, If..then and allOf to apply such constraint but doesn't seem to be working. The below sample input is considered valid by the schema.

Sample JSON input

{
  "myprop": [
    {
      "percent": 0,  <----for metric METRIC1, percent >=0
      "metric": "METRIC1"
    },
    {
      "percent": 0, <----for metric METRIC2, percent > 2 (Validation should have failed)
      "metric": "METRIC2"
    }
  ],
  "anotherProp": [ ... ]
}

Schema below (AllOf doesn't seems to be working).

{
  "definitions": {},
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "http://xxx/policies/performancePolicy",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "myprop": {
      "id": "/properties/myprop",
      "type": "array",
      "items": {
        "id": "/properties/myprop/items",
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "percent": {
            "id": "/properties/myprop/items/properties/percent",
            "type": "number"
          },
          "metric": {
            "id": "/properties/myprop/items/properties/metric",
            "type": "string",
            "enum": [
              "METRIC2",
              "METRIC1",
            ]
          }
        },
        "required": [
          "percent",
          "metric"
        ]
      },
      "uniqueItems": true,
      "minItems": 1,
      "maxItems": 10
    },
    "anotherProp": { ... }
  },
  "required": [
    "myprop",
    "anotherProp"
  ],
  "allOf": [
    {
      "if": { "properties": { "myprop": { "properties": { "metric": { "const": "METRIC2" } } } } },
      "then": { "properties": { "myprop": { "items": { "properties": { "percent": { "minimum": 2 } } } } } } 
    }
  ]
}

Any help would be appreciated.

CodePudding user response:

I see by your $schema keyword that you're using draft 4. if/then/else conditionals weren't introduced until draft 7. You'll need to update your schema to use this draft (shouldn't really be much change).

You can find the differences between the drafts on our specifications page under the section Migrating from older drafts.

Specifically in your case, you'll need to:

  • change the value of $schema to http://json-schema.org/draft-07/schema#
  • change id to $id everywhere
  • change definitions to $defs (but since this is empty it can actually be removed entirely)

I also suggest removing the ids that are just JSON pointers. These don't add value since they can be navigated to easily. (Additionally, if you wanted to have a pointer here, you'd need to URI-encode it.)

Lastly, I'd suggest moving the if/then keywords into the items subschema. There's no reason for it to be at the root since the condition is for each item separately.

  • Related