punkish
punkish

Reputation: 15248

requiring a param with JSON Schema when another param is not present

update: added requirements

I am trying to implement a JSON schema that works like so…

given the following params: foo, bar, baz, one, and two

One of the following should apply

of course, if any params are provided that are not in the schema then an appropriate error should be raised.

After a lot of finagling, and inspiration, here is my attempt which doesn't really work

{
    "type": "object",
    "properties": {
        "foo": { "type": "string" },
        "bar": { "type": "string" },
        "baz": { "type": "string" }
    },
    "oneOf": [
        {
            "not": {
                "properties": { "foo": { "const": "" } },
                "required": []
            }
        },
        { "required": [ "one", "two" ] }
    ]
}

I also tried the following but was not successful

{
    "type": "object",
    "properties": {
        "foo": { "type": "string" },
        "bar": { "type": "string" },
        "baz": { "type": "string" }
    },
    "dependencies": {
        "not": {
            "foo": { "required": ["one", "two"] }
        }
    }
}

Upvotes: 0

Views: 799

Answers (1)

Jason Desrosiers
Jason Desrosiers

Reputation: 24409

I suspect there might be a hidden requirement or two in here, but here's a solution based on your requirements. Let me know if there's something I'm missing and I'll update my answer.

Most of your requirements are the default behavior in JSON Schema, so you don't have to do anything.

  • either no param exists

All properties are optional by default, so nothing to do here

  • if foo exists - then one and two are not required

Again, optional is the default, so nothing to do here

  • if one or more params exist then [and] any param(s) other than foo exist(s) - then one and two are required

The best way to express this is with if/then. If "foo" is optional, it's a little complicated to express, "any param(s) other than foo", so I put that in definitions to make it a bit easier to read.

if any params are provided that are not in the schema then an appropriate error should be raised.

The additionalProperties keyword takes care of this. You just need to add "one" and "two".

{
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "string" },
    "baz": { "type": "string" },
    "one": {},
    "two": {}
  },
  "additionalProperties": false,
  "if": { "$ref": "#/definitions/has-property-other-than-foo" },
  "then": { "required": ["one", "two"] },
  "definitions": {
    "has-property-other-than-foo": {
      "if": { "required": ["foo"] },
      "then": { "minProperties": 2 },
      "else": { "minProperties": 1 }
    }
  }
}

Upvotes: 1

Related Questions