I want to change multiple types (supported in the latest drafts of JSON Schema so does OpenAPI v3.1) to anyOf
, oneOf
but I am a bit confused to which the types would be mapped to. Or can I map to any of the two.
PS. I do have knowledge about anyOf
, oneOf
, etc. but multiple types behavior is a little ambiguous. (I know the schema is invalid but it is just an example that is more focused towards type conversion)
{
"type": ["null", "object", "integer", "string"],
"properties": {
"prop1": {
"type": "string"
},
"prop2": {
"type": "string"
}
},
"enum": [2, 3, 4, 5],
"const": "sample const entry",
"exclusiveMinimum": 1.22,
"exclusiveMaximum": 50,
"maxLength": 10,
"minLength": 2,
"format": "int32"
}
I am converting it this way.
{
"anyOf": [{
"type": "null"
},
{
"type": "object",
"properties": {
"prop1": {
"type": "string"
},
"prop2": {
"type": "string"
}
}
},
{
"type": "integer",
"enum": [2, 3, 4, 5],
"exclusiveMinimum": 1.22,
"exclusiveMaximum": 50,
"format": "int32"
},
{
"type": "string",
"maxLength": 10,
"minLength": 2,
"const": "sample const entry"
}
]
}
First of all, your example is not valid:
The initial schema doesn't match anything, it's an "impossible" schema. The "enum": [2, 3, 4, 5]
and "const": "sample const entry"
constraints are mutually exclusive, and so are "const": "sample const entry"
and "maxLength": 10
.
The rewritten schema is not equivalent to the original schema because the enum
and const
were moved from the root level into subschemas. Yes, this way the schema makes more sense and will sort of work (e.g. it will match the specified numbers - but not strings! because of const
vs maxLength
contradiction), but it's not the same the original schema.
With regard to oneOf
/anyOf
:
It depends.
The choice between anyOf
and oneOf
depends on the context, i.e. whether an instance is can match more than one subschema or exactly one subschema. In other words, whether multiple subschema match is considered OK or an error. Nullable references typically need anyOf
rather than oneOf
, but other cases vary from schema to schema.
For example,
"type": ["number", "integer"]
corresponds to anyOf
because there's an overlap - integer values are also valid "number" values in JSON Schema.
Whereas
"type": ["string", "integer"]
can be represented using either oneOf
or anyOf
. oneOf
is semantically closer since strings and integers are totally different data types with no overlap. But technically anyOf
also works, it's just there won't be more than one subschema match in this particular case.
In your example, all base type
values are distinct with no overlap, so I would use oneOf
, but technically anyOf
will also work.