Schema Composition
Combining Schemas
OpenAPI provides powerful keywords for composing complex schemas from simpler ones. Master these patterns to model inheritance, polymorphism, and union types.
Key Concepts
- • allOf - Combine all schemas (AND) - inheritance, mixins
- • oneOf - Exactly one schema (XOR) - polymorphism
- • anyOf - One or more schemas (OR) - union types
- • discriminator - Property that identifies the type (oneOf/anyOf only)
Which One Should I Use?
| Use Case | Keyword | Example |
|---|---|---|
| Extend a base type with more fields | allOf | Dog extends Animal |
| Combine multiple independent traits | allOf | Pet = Named + Owned + Aged |
| Value is exactly one of several types | oneOf | Pet = Cat | Dog | Bird |
| Accept multiple type variations | anyOf | Accept Cat or Dog or both traits |
| Type detection via property value | discriminator | petType: "cat" or "dog" |
allOf - Inheritance & Composition
ANDCombines multiple schemas into one. The result must satisfy ALL referenced schemas. Use for inheritance (base + extension) or combining traits.
Inheritance Pattern
Dog has: name, age (from Animal) + breed, bark (its own)
Mixin Pattern
User has: id + createdAt, updatedAt + email
oneOf - Polymorphism
XORThe value must match exactly ONE of the listed schemas. Use for polymorphic types where instances are distinct variations (e.g., different payment methods).
Pet Polymorphism Example
Validation Behavior
With oneOf, validation fails if the data matches zero schemas OR multiple schemas. This ensures the value is unambiguously one type.
anyOf - Union Types
ORThe value must match AT LEAST ONE of the listed schemas (can match multiple). More flexible than oneOf - use when schemas might overlap.
Union Type Example
Accepts: "abc123" or 12345
Overlapping Schemas
Valid email also matches ShortText - anyOf allows this
Discriminator
Type TagoneOf/anyOf onlyA property that identifies which schema variant the data belongs to. Improves validation performance and documentation clarity. Note: Discriminator only works with oneOf and anyOf, not allOf.
Discriminator with oneOf
Valid Cat
{
"petType": "cat",
"name": "Whiskers",
"huntsMice": true
}Valid Dog
{
"petType": "dog",
"name": "Rex",
"packAnimal": true
}Discriminator Mapping
When discriminator values don't match schema names, use explicit mapping.
Custom Value Mapping
"petType": "german-shepherd" maps to GermanShepherd schema
Nested Composition
Combine composition keywords for complex type hierarchies.
Base Type with Polymorphic Extension
Common Mistakes
Missing Discriminator Property
When using discriminator, each schema MUST have the discriminator property.
Wrong
Correct
oneOf vs anyOf Confusion
Use oneOf when types are mutually exclusive. Use anyOf when overlap is allowed or intentional. If validation fails because data matches multiple oneOf schemas, consider anyOf.
allOf with Conflicting Properties
When combining schemas with allOf, ensure properties don't conflict. The same property name in multiple schemas should have compatible types.
Best Practices
Always Use Discriminator with oneOf
Makes validation faster and documentation clearer. APIs are easier to use.
Keep Base Schemas Simple
Put only shared properties in base schemas. Let variants add specifics.
Document Each Variant
Add descriptions to each schema in the composition so consumers understand the differences.
Test with Examples
Provide example values for each variant. Tigrister's Preview validates them.