switch (v5 proposal) - sgpinkus/json-schema GitHub Wiki

THIS WIKI IS OBSOLETE. PLEASE SEE THE NEW JSON-SCHEMA-ORG/JSON-SCHEMA-SPEC REPOSITORY.


Note: This proposal has been migrated to https://github.com/json-schema-org/json-schema-spec/issues/64


Proposed keywords

  • switch

Purpose

The purpose of the switch keyword is to express a series of conditional relations: "If A1 then B1, else if A2 then B2, else ...".

This can currently only be specified using repetition, or some rather horrible nested structure based on predicate logic. This keyword would allow schemas to be expressive and concise.

Values

The value of switch is an array. The entries in the array must be objects, each containing:

  • then: a schema or a boolean
  • optional if: a schema
  • optional continue: a boolean

Validation

For each object in the switch array:

  • if if is specified:
    • if data is not valid against the schema in if, then continue to the next item in switch
  • if the value of then is a boolean:
    • if the value of then is false, then validation fails
  • if the value of then is a schema:
    • if the data is not valid against the schema in then, then validation fails
  • if continue is set to boolean true, then:
    • continue to the next item in switch

Example

{
    "type": "object",
    "switch": [
        {
            "if": {
                "properties": {
                    "powerLevel": {"minimum": 9000}
                }
            },
            "then": {
                "required": ["disbelief"]
            }
        },
        {
            "then": {
                "required": ["confidence"]
            }
        }
    ]
}

In this example, a high enough "powerLevel" requires "disbelief", otherwise it requires "confidence".

Note that if the first entry had specified "continue": true, then confidence would be required either way, because the algorithm would not stop when the first entry matched.

Concerns

It's a little verbose for the single case:

{
    "switch": [{
        "if": ...,
        "then": ...
    }]
}

... although it could be worse. The alternative (a plain if/then/else structure) would end up with increasingly nested schemas if you want a series of options.

The point of allowing then to be a boolean is to provide a concise expression to say that the data must be one of the supplied options, e.g.:

{
    "switch": [
        {"if": ..., "then": ...},
        {"if": ..., "then": ...},
        {"then": false}
    ]
}

Discussion