Using OneOf for a property in an OpenAPI spec
When writing an OpenAPI specification, I came across the need for a particular property in an error response to be either a string or an object.
This situation came about when validating a POST request that takes an items property that is a list of objects
As a contrived example of a pet with accessories, consider this example request in curl:
curl -X "POST" "http://api.example.com/pets" \ -H 'Content-Type: application/json' \ -d $'{ "name": "Rover", "items": [ { "name": "collar" "count": 1 }, { "name": "bowl" "count": 2 } ], }'
For the items property, there are two error responses if validation fails:
- Property missing or wrong type.
For example:{ "items": "Items property is required" }
- Missing or invalid sub property
For example on the count property of the second item:{ "items": [ { }, { "count": "Item count must be a positive integer" } ] }
To document this in OpenAPI, I wrote the following for my '400' response (simplified):
'400': description: Validation failed content: application/json: schema: type: object properties: errors: type: object properties: name: type: string example: "Pet name must not be empty" items: oneOf: - $ref: '#/components/schemas/ValidationErrorPetItemsObject' - $ref: '#/components/schemas/ValidationErrorPetItemsString'
Within the components -> schemas section, we define both schemas:
ValidationErrorPetItemsString: type: string example: "Items property is required" ValidationErrorPetItemsPropertyObject: type: array items: type: object properties: id: type: string example: "Item name is required" count: type: string example: "Item count must be a positive integer"
I don’t know how to specify that an empty array will be included so that the client can work out which item object has the problem, so for now it is documented in the description.
There’s probably other ways to solve this, but this is the one I came up with. If there’s a better way, let me know.