OpenAPI Discriminator using oneOf
A minimal example of using a discriminator with an openApi spec and linting with Spectral.
Error message:
~/git/openapi_discriminator/openapi/v1/api.yaml
22:23 error oas3-valid-media-example "example" property must match exactly one schema in oneOf paths./discriminatortest.get.responses[200].content.application/json.example
Background
OpenAPI schema with simple GET method which can return different types of Animal.
A subclass of Animal is defined which can either be a Chicken or a Dog.
The only property Animals have are legs.
A discriminator is used to distinguish between a Chicken or Dog where a Chicken has two legs and a Dog has four legs.
Aim
I was to verify that the example in a request response matches only one schema.
Question
I thought using a discriminator might mean that anything with two legs is a Chicken and anything with four legs is a Dog.
Am I mistaken and it is still legitimate for a Dog to have two legs, and this is why it's erroring?
I could change it to anyOf but then the discriminator has no use?
Code
Code repo - openapi_discriminator
openapi_discriminator/openapi/v1/api.yaml:
openapi: "3.0.3"
info:
title: Open API Discriminator Example
version: "v1"
tags:
- name: discriminator
paths:
/discriminatortest:
get:
tags:
- discriminator
summary: Example using discriminator
description: "Demonstrate a minimal example"
responses:
"200":
description: Created
content:
application/json:
schema: {$ref: "schemas.yaml#/components/schemas/Animal"}
example:
legs: "two"
openapi_discriminator/openapi/v1/schemas.yaml:
openapi: "3.0.3"
components:
schemas:
Animal:
type: object
discriminator:
propertyName: legs
mapping:
two: Chicken
four: Dog
oneOf:
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Chicken'
Chicken:
type: object
required:
- legs
properties:
legs:
type: string
Dog:
type: object
required:
- legs
properties:
legs:
type: string
openapi_discriminator/openapi/.spectral.yml
extends: spectral:oas
rules:
info-contact: false
info-description: false
oas3-api-servers: false
openapi-tags: true
operation-tags: true
operation-operationId: false
operation-description: true
Run linting command: spectral lint "openapi/v1/api.yaml" --ruleset openapi/.spectral.yml
Not sure if you're still looking for an answer, considering you asked this so long ago. The problem here is that you haven't explicitly declared the available values for legs. You know and I know that a dog has four legs and a chicken has two legs, but the schema doesn't. Put another way, the discriminator has to discriminate based only on the value of the
propertyName, so that is what the example has to match.Adding in the
enumvalues will fix your problem:Also, the
mappingis probably not so useful for you right now:Depending on your use case, e.g. if you're generating documentation from the schema, this will mean your generated docs show two options ("two" and "four"). So perhaps you might consider making it: