Reputation: 2331
I'm writing a schema using draft/2020-12
to validate an array of multiple objects. I will be using YAML for the examples for readability (and it's YAML documents that are going to be validated).
I've seen many different approaches but none seem to do a very good job for some reason.
pipeline:
- foo: abc
someOption: 123
- baz: def
anotherOption: 223
- foo: ghi
As you can see, the pipeline
array contains objects that has completely different properties. The same object types can appear multiple times (there's 2 instances of an object containing foo
, they are to be seen as the same object type).
$id: 'https://example.com/schema'
$schema: 'https://json-schema.org/draft/2020-12/schema'
type: object
properties:
pipeline:
type: array
additionalItems: false
anyOf:
- items:
type: object
additionalProperties: false
properties:
foo:
type: string
someOption:
type: integer
required: [foo]
- items:
type: object
additionalProperties: false
properties:
baz:
type: string
anotherOption:
type: integer
required: [baz]
To me, this looks correct, although it fails validation and I can't quite see why...
Even if it had worked, I'm not sure if I'm supposed to use anyOf
or oneOf
in this case. Is it matching across all array items or per individual array item?
Upvotes: 4
Views: 7333
Reputation: 12295
You have it slightly wrong. Currently your schema says... for the pipeline array, either, all of the items must be foo
or all of the items must be baz
.
You need to change your location of anyOf
and items
...
items
applies to every item in the array.
anyOf
checks that any of the subschema values are valid against the instance location (in this case, each item in the array).
{
"$id": "https://example.com/schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"pipeline": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"foo": {
"type": "string"
},
"someOption": {
"type": "integer"
}
},
"required": [
"foo"
]
}, {
"type": "object",
"additionalProperties": false,
"properties": {
"baz": {
"type": "string"
},
"anotherOption": {
"type": "integer"
}
},
"required": [
"baz"
]
}
]
}
}
}
}
Upvotes: 5