Imagine a user writing some config files with some of the properties accepting either a plain value or an array of values of the same type.
The use case is convenience and readability from a user perspective where you don’t want to clutter the file with unnecessary array declaration when a single item is needed.
Here is simple example of what I mean:
{
// valid
"accepted_values": 1,
// valid
"accepted_values": [1, 2, 3],
// invalid
"accepted_values": null
// invalid
"accepted_values": []
}
And associated schema:
{
"properties":{
"accepted_values": {
"oneOf": [
{ "type": "number" },
{
"type": "array",
"items": { "type": "number" },
"minItems": 1
}
]
}
}
}
This same pattern repeats for quite a number a properties, all with different validations of the associated value and I’d like to avoid to create that oneOf
trick every time.
Is there a way to structure the schema so I can reference that pattern with something similar to this:
{
"properties":{
"accepted_values": {
"$ref": "#/one_or_more",
"type": "number",
// Or any other item definition, could be a complex object here
}
}
2
Answers
I am afraid you have to do the
oneOf
trick each time for all different types you need. You can assign the defined patterns to each property using$ref
according to the type the property has to be.There is no thing like a "template" to set the type.
Edit: You can avoid the
oneOf
as shown in the answer of Jason from above. The approach is still the same.There is a way to create a generic type with dynamic references, but it turns out to be more complicated and verbose than probably make sense for this case.
There’s an alternative way to express this schema that is less verbose because it drops the
oneOf
.This works because the
items
andminItems
keywords only apply if the instance is an array. There’s still some duplication, but it’s as concise as it’s going to get.If you’re using these multiple times, you can use definitions to reduce the boilerplate a bit more.