GraphQL API Design

Using GraphQL @oneOf Inputs in Modern API Design

How OneOf Input Objects express exclusive alternatives, improve validation and tooling, and replace ambiguous input combinations without moving business rules into the schema.

API inputs frequently need to express a choice: find a customer by ID or email, pay by card or bank account, create a notification for email or SMS, or select one of several filter shapes. A normal GraphQL input object makes every field optional but cannot state that exactly one alternative is required.

The September 2025 GraphQL specification defines OneOf Input Objects for this case. An input marked with @oneOf must contain exactly one field, and that field’s value must be non-null. The contract becomes visible to validation and introspection instead of depending on prose or resolver checks alone.

Diagram for Using GraphQL @oneOf Inputs in Modern API DesignONEOF INPUT COERCIONUserLookup @oneOfid • email • externalRefchoose exactly oneVALID SHAPE{ id: "42" }One entry • non-nullTyped alternativeValidate + authorizein application codeREJECT: EMPTY{ }REJECT: MULTIPLE{ id, email }REJECT: NULL{ id: null }
A OneOf Input Object accepts exactly one non-null alternative and rejects ambiguous or empty shapes during coercion.

1. Recognize an exclusive input relationship

Use @oneOf when the alternatives represent different shapes of the same conceptual choice. A lookup condition may accept an ID, username, or compound organization-and-email input. A payment method may accept card, bank transfer, or wallet details.

Do not use it merely because fields happen to be optional. Inputs such as profile updates commonly allow several fields together and remain normal input objects. The defining rule is exactly one alternative, not ‘at least one’ or ‘some combination.’

2. Understand the schema and coercion rules

A OneOf Input Object is declared by adding @oneOf to the input definition. Every field must be nullable and must not define a default value. During coercion, the provided object must contain exactly one entry and its value must not be null.

Introspection exposes the distinction through __Type.isOneOf, allowing capable tooling and code generators to represent the input as a discriminated union or equivalent exclusive type. This is safer than generating a class where every alternative appears independently optional.

  • Zero fields is invalid
  • Two or more fields is invalid
  • One field with a null value is invalid
  • All normal input-object coercion rules still apply
  • OneOf extensions must preserve nullable fields without defaults

3. Prefer explicit alternatives over mode fields

A common workaround combines a mode enum with several optional fields. That design permits contradictory states such as mode EMAIL with both email and phone values, and every client must reproduce the validation matrix.

With @oneOf, the selected field is the discriminator. Give each alternative a descriptive name and use a nested input when the option requires several values. The schema then communicates the valid shapes directly.

4. Keep business validation beyond @oneOf

@oneOf validates structure, not business meaning. A syntactically selected card input can still contain an expired token, a customer ID may belong to another tenant, and a date range may violate product policy. Resolvers and application services must continue to authorize and validate the selected value.

Map the coerced alternative into an application command or discriminated union and make exhaustive handling visible in code. Avoid a default branch that silently ignores newly added schema alternatives.

5. Introduce OneOf inputs compatibly

Changing an existing normal input object to @oneOf can break clients that currently provide several fields, null values, or defaults. Add a new argument or mutation version, measure adoption, publish generated-client guidance, and deprecate the ambiguous input gradually.

Confirm support across the server, schema registry, gateway, client code generator, IDE, persisted-operation validation, and testing stack. The specification contract is current, but implementation support and generated type quality still vary by ecosystem and version.

Key takeaways

What to carry into your next decision

  • Use @oneOf only when an input must select exactly one alternative.
  • Every OneOf field is nullable, has no default, and the selected value must be non-null.
  • Let @oneOf express structural exclusivity while application code enforces business rules.
  • Introduce it as a versioned contract change and verify ecosystem support.

Sources and further reading

Version-specific and platform guidance was checked against these primary sources.

  1. GraphQL specification: OneOf Input Objects
  2. GraphQL specification: Input Objects
  3. GraphQL specification: Type introspection