Using OpenAPI Discriminator for Polymorphic Request and Response Bodies
Learn how to model polymorphic payloads with an OpenAPI discriminator, see a worked Pet/Cat/Dog example, and understand validation limits and common pitfalls.
02 Mar 2026, 07:42 UTC

When to use an OpenAPI discriminator
If a single endpoint must accept or return several distinct object shapes that share a common identifying field, model the polymorphism with an OpenAPI discriminator keyword. This keeps the API surface small, lets generators produce type hierarchies, and documents the dispatch logic directly in the schema.
Worked example: Pet API
The following YAML snippet shows a base Pet schema with a discriminator on the petType property. Two subtypes, Cat and Dog, extend Pet and add their own required fields.
openapi: 3.1.0
info:
title: Pet Store API
version: 1.0.0
paths:
/pets:
post:
summary: Create a pet
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
responses:
'200':
description: Created pet
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
components:
schemas:
Pet:
type: object
required:
- petType
- name
discriminator:
propertyName: petType
mapping:
cat: '#/components/schemas/Cat'
dog: '#/components/schemas/Dog'
properties:
petType:
type: string
enum: [cat, dog]
name:
type: string
Cat:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
required:
- likesFish
properties:
likesFish:
type: boolean
Dog:
allOf:
- $ref: '#/components/schemas/Pet'
- type: object
required:
- breed
properties:
breed:
type: string
How it works:
- The
discriminatorkeyword tells consumers that the value ofpetTypedetermines which referenced schema should be used for validation. - When a client sends a JSON body with
{"petType":"cat","name":"Whiskers","likesFish":true}, the validator matches thepetTypevalue to the mapping and validates against theCatschema. - Server‑side code generated from this document (e.g., via
openapi-generator) will typically produce a basePetclass with subclassesCatandDog, allowing the developer to switch onpetTypeor use polymorphism directly.
Limits and considerations
- The discriminator does not> add runtime validation; it only influences schema resolution and documentation. You still need server‑side code to check the discriminator value if you rely on it for routing.
- Tooling support varies: some validators (e.g.,
Spectral) fully enforce the mapping, while others may ignore it or produce warnings for missing properties. - Deeply nested polymorphism can lead to ambiguous
oneOfmatches that are hard to read and may cause generators to produce overlapping types. - OpenAPI 3.0 uses a simple mapping object; OpenAPI 3.1 aligns the discriminator with JSON Schema’s
discriminatorkeyword, so behavior can differ between versions.
Common mistakes
- Forgetting to make the discriminator property
requiredin the base schema – without it, clients cannot reliably dispatch. - Using mapping keys that do not match the actual enum values sent on the wire (e.g., mapping
felinewhile the API sendscat). - Omitting
oneOforanyOfalongside the discriminator, which leaves the schema undocumented and can confuse generators. - Assuming the discriminator enforces that subtypes cannot have additional properties beyond those defined; it does not, so extra fields may slip through validation.
How to verify the discriminator works
- Validate the document – run an OpenAPI linter that understands discriminators. Example using Spectral (requires Node.js and read access to the file):
Expected output: no errors related to unresolvednpx @stoplight/spectral-cli lint openapi.yaml$refor missing discriminator property. - Generate client/server stubs – use your preferred generator and inspect the output for subtype classes. Example with OpenAPI Generator (Java):
Check thatopenapi-generator generate -i openapi.yaml -g java -o ./generated-javaPet.javaexists and thatCat.javaandDog.javaextend it. - Test payloads – send sample JSON bodies for each subtype and confirm the server deserializes to the correct type (or that a client parses them into the expected class). This step requires permission to call the API or run unit tests against the generated code.
Look for a response that includes thecurl -X POST http://localhost:8080/pets \ -H "Content-Type: application/json" \ -d '{"petType":"dog","name":"Rex","breed":"Labrador"}'breedfield, indicating theDogschema was applied. - If any step fails, review the discriminator property name, mapping values, and required fields in the base schema.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.