Understanding oneOf in OpenAPI (Without the Confusion)

Published: (December 23, 2025 at 02:00 AM EST)
2 min read
Source: Dev.to

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 → use InverterPatch → 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 oneOf unless you actually need schema selection.

Used correctly, oneOf makes your API safer and self‑documenting. Used incorrectly, it makes PATCH endpoints painful.

Back to Blog

Related posts

Read more »