Understanding oneOf in OpenAPI (Without the Confusion)
Source: Dev.to
Introduction
When designing APIs with OpenAPI, oneOf often looks intimidating. It’s powerful, but easy to misuse—especially with PATCH endpoints. Let’s break it down simply.
What oneOf Means in OpenAPI (JSON Schema)
- The request body must match exactly one schema from the list.
- Not zero.
- Exactly one.
Example
schema:
oneOf:
- $ref: '#/components/schemas/InverterPatch'
- $ref: '#/components/schemas/EVPatch'
- $ref: '#/components/schemas/EVCSPatch'
This tells OpenAPI: “The payload must conform to exactly one of these schemas.”
oneOf Is Tricky with PATCH
PATCH requests are partial updates. Clients often send only a few fields.
Imagine this payload:
{
"reverseFlow": true
}
If reverseFlow exists in both InverterPatch and EVCSPatch, the payload matches more than one schema.
🚫 Result: Validation fails, because oneOf requires exactly one match.
Using a Discriminator to Resolve Ambiguity
discriminator:
propertyName: type
Now the client sends:
{
"type": "inverter",
"reverseFlow": true
}
OpenAPI immediately knows:
type = inverter→ useInverterPatch→ validation succeeds.
💡 The discriminator tells OpenAPI which schema to validate against.
When to Use oneOf (with a Discriminator)
- You have multiple schemas.
- Some fields overlap.
- Clients may send partial updates.
- You want OpenAPI‑level validation, not just backend logic.
When to Avoid oneOf
- You don’t need OpenAPI to pick between schemas.
- The backend already knows the resource type.
- You’re okay validating type‑specific rules at runtime.
In those cases, a single PATCH schema with optional fields is simpler and often better.
Summary
oneOf= exactly one schema must match.- Overlapping fields +
PATCH= ambiguity. - A discriminator resolves that ambiguity.
- Don’t use
oneOfunless you actually need schema selection.
Used correctly, oneOf makes your API safer and self‑documenting. Used incorrectly, it makes PATCH endpoints painful.