Karmanya Aggarwal
Karmanya Aggarwal

Reputation: 548

JSON Schema draft 07 if then statements for conditional validation

I'm trying to create a schema that has a slightly different structure depending upon values and decided to use draft 07 and ajv to validate it. The structure I'm trying to create is as follows -

   "url":{
   "some-random-string":{
            "pattern":"somevalue",
            "handler":"one-of-a-few-allowed-values",
            "kwargs":{ "conditional object" with further constraints}
             }
   }

of this, pattern is required, and certain kwargs objects will have other required keys. I tried using a series of if..then statements combined with a reference as follows :

   "url": {
  "type": "object",
  "patternProperties": {
    "^.*$": {
      "properties": {
        "pattern": {
          "type": "string"
        },
        "handler": {
          "type": "string",
          "enum": ["val1","val2"...
          ]
        }
      },
      "required": ["pattern"],
       "if": {
          "properties": {
            "handler": {
              "enum": ["val1"]
            }
          }
        },
        "then": {
          "properties": {
            "kwargs": {
              "$ref": "#/definitions/val1"
            }
          }
        },
        "if": {
          "properties": {
            "handler": {
              "enum": ["val2"]
            }
          }
        },
        "then": {
          "properties": {
            "kwargs": {
              "$ref": "#/definitions/val2"
            },"required":["function"]
          }
        },

the required pattern constraint works, the required function constraint does not.

I even tried wrapping up all of the if-then statements into an allOf array, with each set of if-then inside one object, but it doesn't seem to work.

the reference currently looks like this

     "val2": {
  "type": ["object", "boolean"],
  "properties": {
    "kwargs": {
      "type": "object",
      "properties": {
        "function": {
          "type": "string"
        },
        "methods": {
          "type": "array",
          "items": {
            "enum": ["GET", "PUT", "POST", "DELETE", "OPTIONS"]
          }
        }
      }
    }
  }
}

Upvotes: 0

Views: 2615

Answers (1)

vearutop
vearutop

Reputation: 4062

This schema uses if to check if handler is present in data, then it checks handler value with const in anyOf context.

{
  "properties": {
    "url": {
      "type": "object",
      "patternProperties": {
        "^.*$": {
          "properties": {
            "pattern": {"type": "string"},
            "handler": {
              "type": "string",
              "enum": ["val1", "val2"]
            }
          },
          "required": ["pattern"],
          "if": {"required": ["handler"]},
          "then": {
            "anyOf": [
              {
                "properties": {
                  "handler": {"const": "val1"},
                  "kwargs": {"$ref": "#/definitions/val1"}
                }
              },
              {
                "properties": {
                  "handler": {"const": "val2"},
                  "kwargs": {"$ref": "#/definitions/val2"}
                }
              }
            ]
          }
        }
      }
    }
  },
  "definitions": {
    "val1": {
      "type": "string"
    },
    "val2": {
      "type": "integer"
    }
  }
}

Upvotes: 3

Related Questions