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
enum
values will fix your problem:Also, the
mapping
is 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: