Skip to content

Commit 6809c39

Browse files
committed
Editorial
1 parent 98eff7f commit 6809c39

File tree

1 file changed

+47
-35
lines changed

1 file changed

+47
-35
lines changed

website/pages/docs/abstract-types.mdx

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: Abstract types in GraphQL.js
55
GraphQL includes two kinds of abstract types: interfaces and unions. These types let a single
66
field return values of different object types, while keeping your schema type-safe.
77

8-
This guide covers how to define and resolve abstract types using GraphQL.js. It focuses on
8+
This guide covers how to define and resolve abstract types using GraphQL.js. It focuses on
99
constructing types in JavaScript using the GraphQL.js type system, not the schema definition
1010
language (SDL).
1111

@@ -22,21 +22,25 @@ flexibility while preserving validation, introspection, and tool support.
2222
GraphQL provides two kinds of abstract types:
2323

2424
- Interfaces define a set of fields that multiple object types must implement.
25-
- Use case: A `ContentItem` interface with fields like `id`, `title`, and `publishedAt`,
25+
- Use case: A `ContentItem` interface with fields like `id`, `title`, and `publishedAt`,
2626
implemented by types such as `Article` and `PodcastEpisode`.
2727
- Unions group together unrelated types that don't share any fields.
28-
- Use case: A `SearchResult` union that includes `Book`, `Author`, and `Publisher` types.
28+
- Use case: A `SearchResult` union that includes `Book`, `Author`, and `Publisher` types.
2929

3030
## Defining interfaces
3131

3232
To define an interface in GraphQL.js, use the `GraphQLInterfaceType` constructor. An interface
33-
must include a `name`, a `fields` function, and a `resolveType` function, which tells GraphQL which
34-
concrete type a given value corresponds to.
33+
must include a `name`, definition of the shared `fields`, and should include a `resolveType`
34+
function telling GraphQL which concrete type a given value corresponds to.
3535

3636
The following example defines a `ContentItem` interface for a publishing platform:
3737

38-
```js
39-
const { GraphQLInterfaceType, GraphQLString, GraphQLNonNull } = require('graphql');
38+
```js filename="ContentItemInterface.js"
39+
const {
40+
GraphQLInterfaceType,
41+
GraphQLString,
42+
GraphQLNonNull,
43+
} = require('graphql');
4044

4145
const ContentItemInterface = new GraphQLInterfaceType({
4246
name: 'ContentItem',
@@ -55,10 +59,13 @@ const ContentItemInterface = new GraphQLInterfaceType({
5559
return null;
5660
},
5761
});
62+
63+
exports.ContentItemInterface = ContentItemInterface;
5864
```
5965

60-
You can return either the type name as a string or the corresponding `GraphQLObjectType` instance.
61-
Returning the instance is recommended when possible for better type safety and tooling support.
66+
The `resolveType` function must return either the string type name corresponding
67+
to the `GraphQLObjectType` of the given `value`, or `null` if the type could not
68+
be determined.
6269

6370
## Implementing interfaces with object types
6471

@@ -70,6 +77,7 @@ conform to the `ContentItem` interface:
7077

7178
```js
7279
const { GraphQLObjectType, GraphQLString, GraphQLNonNull } = require('graphql');
80+
const { ContentItemInterface } = require('./ContentItemInterface.js');
7381

7482
const ArticleType = new GraphQLObjectType({
7583
name: 'Article',
@@ -105,11 +113,8 @@ GraphQL uses `resolveType`.
105113
Use the `GraphQLUnionType` constructor to define a union. A union allows a field to return one
106114
of several object types that don't need to share fields.
107115

108-
A union requires:
109-
110-
- A `name`
111-
- A list of object types (`types`)
112-
- A `resolveType` function
116+
A union requires a name and a list of object types (`types`). It should also be
117+
provided a `resolveType` function the same as explained for interfaces above.
113118

114119
The following example defines a `SearchResult` union:
115120

@@ -134,39 +139,42 @@ const SearchResultType = new GraphQLUnionType({
134139
});
135140
```
136141

137-
Unlike interfaces, unions don’t declare any fields of their own. Clients use inline fragments
138-
to query fields from the concrete types.
142+
Unlike interfaces, unions don’t declare any fields their members must implement.
143+
Clients use a fragment with a type condition to query fields from a concrete type.
139144

140145
## Resolving abstract types at runtime
141146

142-
GraphQL resolves abstract types dynamically during execution using the `resolveType` function.
147+
GraphQL resolves abstract types dynamically during execution using the `resolveType` function, if
148+
present.
143149

144150
This function receives the following arguments:
145151

152+
<!-- prettier-ignore -->
146153
```js
147154
resolveType(value, context, info)
148155
```
149156

150157
It can return:
151158

152-
- A `GraphQLObjectType` instance (recommended)
153159
- The name of a type as a string
160+
- `null` if the type could not be determined
154161
- A `Promise` resolving to either of the above
155162

156-
If `resolveType` isn't defined, GraphQL falls back to checking each possible type's `isTypeOf`
163+
If `resolveType` isn't defined, GraphQL falls back to checking each possible type's `isTypeOf`
157164
function. This fallback is less efficient and makes type resolution harder to debug. For most cases,
158165
explicitly defining `resolveType` is recommended.
159166

160167
## Querying abstract types
161168

162-
To query a field that returns an abstract type, use inline fragments to select fields from the
163-
possible concrete types. GraphQL evaluates each fragment based on the runtime type of the result.
169+
To query a field that returns an abstract type, use fragments to select fields from the possible
170+
concrete types. GraphQL evaluates each fragment based on the runtime type of the result.
164171

165172
For example:
166173

167174
```graphql
168-
{
169-
search(term: "deep learning") {
175+
query Search($term: String! = "deep learning") {
176+
search(term: $term) {
177+
# Inline fragments with type condition:
170178
... on Book {
171179
title
172180
isbn
@@ -175,30 +183,34 @@ For example:
175183
name
176184
bio
177185
}
178-
... on Publisher {
179-
name
180-
catalogSize
181-
}
186+
# Named fragment:
187+
...publisherFrag
182188
}
183189
}
190+
191+
fragment publisherFrag on Publisher {
192+
name
193+
catalogSize
194+
}
184195
```
185196

186197
GraphQL's introspection system lists all possible types for each interface and union, which
187-
enables code generation and editor tooling to provide type-aware completions.
198+
enables code generation and editor tooling to provide type-aware completions; however you should
199+
keep in mind the possibility that more types will implement the interface or be included in the
200+
union in future, and thus ensure that you have a default case to handle additional types.
188201

189202
## Best practices
190203

191204
- Always implement `resolveType` for interfaces and unions to handle runtime type resolution.
192-
- Return the `GraphQLObjectType` instance when possible for better clarity and static analysis.
193205
- Keep `resolveType` logic simple, using consistent field shapes or tags to distinguish
194-
types.
195-
- Test `resolveType` logic carefully. Errors in `resolveType` can cause runtime errors that can
196-
be hard to trace.
206+
types.
207+
- Test `resolveType` logic carefully. Errors in `resolveType` can cause runtime errors that can
208+
be hard to trace.
197209
- Use interfaces when types share fields and unions when types are structurally unrelated.
198210

199211
## Additional resources
200212

201213
- [Constructing Types](https://www.graphql-js.org/docs/constructing-types/)
202-
- GraphQL Specification:
203-
- [Interfaces](https://spec.graphql.org/October2021/#sec-Interfaces)
204-
- [Unions](https://spec.graphql.org/October2021/#sec-Unions)
214+
- GraphQL Specification:
215+
- [Interfaces](https://spec.graphql.org/October2021/#sec-Interfaces)
216+
- [Unions](https://spec.graphql.org/October2021/#sec-Unions)

0 commit comments

Comments
 (0)