From 4e7dc0640ef21418b20bd59709334675a4437fc6 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Fri, 6 Jun 2025 15:11:23 +0100 Subject: [PATCH] Add oneOf blog post --- .prettierignore | 1 + .../index.mdx | 106 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 src/pages/blog/2025-06-19-multioption-inputs-with-oneof/index.mdx diff --git a/.prettierignore b/.prettierignore index ebb39d2d73..893da2157f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -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 diff --git a/src/pages/blog/2025-06-19-multioption-inputs-with-oneof/index.mdx b/src/pages/blog/2025-06-19-multioption-inputs-with-oneof/index.mdx new file mode 100644 index 0000000000..81a04e2ebd --- /dev/null +++ b/src/pages/blog/2025-06-19-multioption-inputs-with-oneof/index.mdx @@ -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!