Skip to content

Add oneOf blog post #2011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: source
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ pnpm-lock.yaml
!src/pages/blog/2024-08-15-graphql-local-initiative.mdx
!src/pages/community/foundation/community-grant.mdx
!src/pages/blog/2025-06-01-graphiql-4/index.mdx
!src/pages/blog/2025-06-19-multioption-inputs-with-oneof/index.mdx
*.jpg
106 changes: 106 additions & 0 deletions src/pages/blog/2025-06-19-multioption-inputs-with-oneof/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: Safer Multi-option Inputs with `@oneOf`
tags: [announcements, spec]
date: 2025-06-19
byline: Benjie Gillam
---

We’re excited to announce
**[OneOf Input Objects](https://github.com/graphql/graphql-spec/pull/825)** has
landed in the GraphQL specification! This enhancement solves a long-standing
challenge in API design: how to allow users to provide **exactly one** of
several possible options as input, in a clean and enforceable way. This feature
is a small change that packs a big return for developers building modern digital
products with GraphQL.

## Simplifying entrypoints

Most GraphQL queries start at a single node, and traverse the data graph from
there. But often, there is more than one way of locating that node; for example
you might find a user by their ID, email address, or username. Traditionally,
that meant multiple root-level fields:

```graphql
type Query {
user(id: ID!): User
userByEmail(email: String!): User
userByUsername(username: String!): User
}
```

_(An alternative approach was a less-than-type-safe field presenting all the
options along with custom runtime validation to enforce the constraints. Either
way, neither solution was ideal.)_

With `@oneOf`, you can now consolidate those options into a single,
user-friendly input which ensures users supply _exactly one_ input field, the
value of which must not be null. The result: a user-friendly schema with fewer
root-level fields and without sacrificing type safety:

```graphql
input UserBy @oneOf {
id: ID
email: String
username: String
}

type Query {
user(by: UserBy!): User
}
```

## Input polymorphism

Of course, `@oneOf`'s use isn't limited to simple scalars — it can also be used
to choose between multiple complex input types, allowing for polymorphism in
GraphQL inputs.

Imagine you were building a user-friendly blogging website, and each post is
made up of elements — paragraphs, image galleries, block quotes, code blocks,
and the like. Each of these elements come with their own set of (potentially
overlapping) attributes, and you want to feed a list of them into your mutation.
With @oneOf you can do so in a type safe manner:

```graphql
type Mutation {
createPost(elements: [PostElementInput]): Post
}
input PostElementInput @oneOf {
paragraph: ParagraphInput
blockquote: BlockQuoteInput
gallery: GalleryInput
}
input ParagraphInput {
text: String!
}
input BlockQuoteInput {
text: String!
attribution: String
attributionUrl: String
}
input GalleryInput {
imageUrls: [String!]!
caption: String
attribution: String
}
```

## What Makes `@oneOf` The Right Solution?

- **Backward Compatible**: Existing tools, queries and clients still work,
meaning no major overhauls are required. Existing clients can even use oneOf
inputs without updating; just be careful to always supply exactly one value!
- **Minimal Complexity**: This feature introduces only a small change to the
existing type system, but delivers very significant benefits.
- **Type-Safe Input Polymorphism**: Offers a safe and scalable way to accept a
variety of inputs under a single structure—something previously hard to
achieve in GraphQL.
- **Now part of the GraphQL standard:** Several GraphQL implementations
including Ruby, Java, JavaScript and .NET already ship `@oneOf` as a stable
feature

## The Bottom Line

`@oneOf` allows for more expressive, capable, and less overwhelming schemas,
helping technical teams to move faster with increased safety. It’s simple and
easy to implement, try it today!