75

I would like to know if I can define a JSON schema (draft 4) that requires at least one of many properties possible for an object. I already know of allOf, anyOf and oneOf but just can't figure out how to use them in the way I want.

Here are some example JSON to illustrate :

// Test Data 1 - Should pass { "email": "[email protected]", "name": "John Doe" } // Test Data 2 - Should pass { "id": 1, "name": "Jane Doe" } // Test Data 3 - Should pass { "id": 1, "email": "[email protected]", "name": "John Smith" } // Test Data 4 - Should fail, invalid email { "id": 1, "email": "thisIsNotAnEmail", "name": "John Smith" } // Test Data 5 - Should fail, missing one of required properties { "name": "John Doe" } 

I would like to require at least id or email (also accepting both of them) and still pass validation according to format. Using oneOf fails validation if I provide both (test 3), anyOf passes validation even if one of them is not valid (test 4)

Here is my schema :

{ "$schema": "http://json-schema.org/draft-04/schema#", "id": "https://example.com", "properties": { "name": { "type": "string" } }, "anyOf": [ { "properties": { "email": { "type": "string", "format": "email" } } }, { "properties": { "id": { "type": "integer" } } } ] } 

Can you help me how to achieve correct validation for my use case ?

2 Answers 2

148

To require at least one of a set of properties, use required inside a series of anyOf options:

{ "type": "object", "anyOf": [ {"required": ["id"]}, {"required": ["email"]} // any other properties, in a similar way ], "properties": { // Your actual property definitions here } } 

If any of the properties you want is present ("id", "email"), then it will pass the corresponding option in allOf.

Sign up to request clarification or add additional context in comments.

Comments

44

You may use minProperties: number (and maxProperties: number if needed). That would shorten the schema definition:

{ "type": "object", "minProperties": 1, "properties": [/* your actual properties definitions */], "additionalProperties": false } 

Link to documentation: https://json-schema.org/understanding-json-schema/reference/object.html#size

4 Comments

This is actually a bad solution, because an object, that contains none of the properties defined in the schema while having properties that are not present in the schema, will still validate. Example: { "foo": "bar" } will validate against { "type": "object", "minProperties": 1, "properties": { "test": { "type": "string" }, "bar": { "type": "string" } } }.
@Benni what about "additionalProperties": false then?
That would work. Read more here.
Hi, just adding something else, this aproach works better if you require at least two or more proterties. i.e. you require an id and an additional required property. (e.g. updating a record) (adding "required": ["id"] and setting "minProperties": 2,)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.