Skip to content

Commit

Permalink
Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: Benjie <[email protected]>
  • Loading branch information
JoviDeCroock and benjie committed Nov 8, 2024
1 parent 6503fd6 commit 34a6ed7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 10 deletions.
1 change: 1 addition & 0 deletions cspell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ words:
- tailwindcss
- svgr
- ruru
- oneof

# used as href anchors
- graphqlerror
Expand Down
2 changes: 1 addition & 1 deletion website/pages/_meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const meta = {
title: 'Advanced Guides',
},
'constructing-types': '',
'input-unions': '',
'oneof-input-objects': 'OneOf input objects',
'defer-stream': '',
'-- 3': {
type: 'separator',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
title: Input Unions
title: OneOf input objects
---

import { Tabs } from 'nextra/components';

Some inputs will behave differently depending on what input we choose. Let's look at the case for
a field named `product`, we can fetch a `Product` by either its `id` or its `name`. Currently we'd
make a tradeoff for this by introducing two arguments that are both nullable, now if both are passed
as null we'd have to handle that in code. To fix this the `@oneOf` directive was introduced so we
can create these input-unions without sacrificing the strictly typed nature of our GraphQL Schema.
as null (or both non-null) we'd have to handle that in code - the type system wouldn't indicate that exactly one was required. To fix this, the `@oneOf` directive was introduced so we
can create this "exactly one option" constraint without sacrificing the strictly typed nature of our GraphQL Schema.

<Tabs items={['SDL', 'Code']}>
<Tabs.Tab>
Expand All @@ -19,13 +19,20 @@ const schema = buildSchema(`
name: String!
}
input ProductInput @oneOf {
input ProductLocation {
aisleNumber: Int!
shelfNumber: Int!
positionOnShelf: Int!
}
input ProductSpecifier @oneOf {
id: ID
name: String
location: ProductLocation
}
type Query {
product(input: ProductInput!): Product
product(by: ProductSpecifier!): Product
}
`);
```
Expand All @@ -44,12 +51,23 @@ const Product = new GraphQLObjectType({
},
});

const ProductInput = new GraphQLInputObjectType({
name: 'ProductInput',
const ProductLocation = new GraphQLInputObjectType({
name: 'ProductLocation',
isOneOf: true,
fields: {
aisleNumber: { type: GraphQLInt },
shelfNumber: { type: GraphQLInt },
positionOnShelf: { type: GraphQLInt },
},
});

const ProductSpecifier = new GraphQLInputObjectType({
name: 'ProductSpecifier',
isOneOf: true,
fields: {
id: { type: GraphQLID },
name: { type: GraphQLString },
location: { type: ProductLocation },
},
});

Expand All @@ -59,7 +77,7 @@ const schema = new GraphQLSchema({
fields: {
product: {
type: Product,
args: { input: { type: ProductInput } },
args: { by: { type: ProductSpecifier } },
},
},
}),
Expand All @@ -69,4 +87,5 @@ const schema = new GraphQLSchema({
</Tabs>

It doesn't matter whether you have 2 or more inputs here, all that matters is
that your user will have to specify one, and only one, for this input to be valid.
that your user will have to specify one, and only one, for this input to be valid.
The values are not limited to scalars, lists and other input object types are also allowed.

0 comments on commit 34a6ed7

Please sign in to comment.