You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/graphql/resolvers-map.md
+21-17Lines changed: 21 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,9 +6,9 @@ Resolvers provide the instructions for turning a [GraphQL](https://graphql.org/)
6
6
7
7
In the code first approach, we don't write GraphQL SDL by hand. Instead we use TypeScript decorators. The `@nestjs/graphql` package will then read the metadata defined through these decorators and automatically generate the schema for you.
8
8
9
-
Most of the definitions in a GraphQL schema are **object types**. Each object type you define should represent an object that an application client might need to interact with. For example, our sample API needs to be able to fetch a list of authors and their posts, so we should define the `Author` type and `Post` type to support this functionality.
9
+
Most of the definitions in a GraphQL schema are **object types**. Each object type you define should represent a domain object that an application client might need to interact with. For example, our sample API needs to be able to fetch a list of authors and their posts, so we should define the `Author` type and `Post` type to support this functionality.
10
10
11
-
In the schema first approach, we'd define such a schema with SDL like this:
11
+
If we were using the schema first approach, we'd define such a schema with SDL like this:
import { Field, Int, ObjectType } from '@nestjs/graphql';
@@ -41,19 +41,21 @@ export class Author {
41
41
}
42
42
```
43
43
44
-
> info **Hint** TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. Thus, we must either use the `@Field` decorator or use a [CLI plugin](/graphql/resolvers#cli-plugin).
44
+
> info **Hint** TypeScript's metadata reflection system has several limitations which make it impossible to, for instance, determine what properties a class consists of or recognize whether a given property is optional or required. Because of these limitations, we must either explicitly use the `@Field` decorator in our schema definition classes, or use a [CLI plugin](/graphql/resolvers#cli-plugin) to generate these for us.
45
45
46
-
The `Author` object type has a collection of fields. Each field has a type. A field's type can be either an object type or a scalar type. A scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value. In addition to GraphQL's built-in scalar types, you can define custom scalar types.
46
+
The `Author` object type, like any class, is made of a collection of fields, with each field declaring a type. The types correspond to [GraphQL types](https://graphql.org/learn/schema/). A field's GraphQL type can be either an object type or a scalar type. A scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value.
47
+
48
+
> info **Hint** In addition to GraphQL's built-in scalar types, you can define custom scalar types.
47
49
48
50
The above `Author` object type definition will generate the SDL we showed above.
49
51
50
-
The `@Field()` decorator accepts an optional function returning a type (e.g., `type => Int`), and optionally an object with the following keys:
52
+
The `@Field()` decorator accepts a type function (e.g., `type => Int`), and optionally an object with the following keys:
51
53
52
-
-`nullable`: for specifying whether a field is nullable (in SDL, each field is non-nullable by default)
53
-
-`description`: for setting a field description
54
-
-`deprecationReason`: for marking a field as deprecated
54
+
-`nullable`: for specifying whether a field is nullable (in SDL, each field is non-nullable by default); `boolean`
55
+
-`description`: for setting a field description; `string`
56
+
-`deprecationReason`: for marking a field as deprecated; `string`
> info **Hint** With `[ ]`, we can determine the depth of the array. For example, using `[[Int]]` would represent an integer matrix.
73
75
74
-
To declare that the array's items (not the array itself) are nullable, set the `nullable` property to `'items'` as shown below:
76
+
To declare that an array's items (not the array itself) are nullable, set the `nullable` property to `'items'` as shown below:
75
77
76
78
```typescript
77
79
@Field(type=> [Post], { nullable: 'items' })
@@ -137,12 +139,14 @@ export class AuthorResolver {
137
139
138
140
> warning **Warning** The logic inside the `AuthorsService` and `PostsService` classes can be as simple or sophisticated as needed. The main point of this example is to show how to construct resolvers and how they can interact with other providers.
139
141
140
-
In the example above, we created the `AuthorResolver` which defines one query and one field resolver function. To create a resolver, we annotate the class with the `@Resolver()` decorator. The argument passed in to the `@Resolver()` decorator is optional, but in our case, since we have also defined a **field resolver** (for the `posts` property of the `Author` object type), it becomes required; in that case, the value is used to indicate which class is the parent (type) for any field resolver defined within this class.
142
+
In the example above, we created the `AuthorResolver` which defines one query and one field resolver function. To create a resolver, we create a class with resolver functions as methods, and we annotate the class with the `@Resolver()` decorator.
141
143
142
-
We can define multiple `@Query()`resolver functions (both within this class, and in any other resolver class), and they will be aggregated into a single **Query type**definition in the generated SDL and the appropriate entries in the resolver map. This allows you to create queries close to the models and services that they use, and to keep them well organized in modules.
144
+
The argument passed to the `@Resolver()`decorator is optional. However, in our case, since we have also defined a **field resolver**(for the `posts` property of the `Author` object type), it becomes required; in that case, the value is used to indicate which class is the parent type (i.e., the corresponding `ObjectType` class name) for any field resolver defined within this class.
143
145
144
146
In this example, we defined a query handler to get the author object based on the `id` sent in the request. To specify that the method is a query handler, use the `@Query()` decorator.
145
147
148
+
We can define multiple `@Query()` resolver functions (both within this class, and in any other resolver class), and they will be aggregated into a single **Query type** definition in the generated SDL along with the appropriate entries in the resolver map. This allows you to define queries close to the models and services that they use, and to keep them well organized in modules.
149
+
146
150
In the above examples, the `@Query()` decorator generates a query type name based on the method name. For example, consider the following construction from the example above:
- description: adescriptionthatwillbeusedtogenerateGraphQLschema documentation (e.g. in GraphQL playground); a `string`
@@ -204,7 +208,7 @@ Usually you won't have to pass an object into the `@Args()` decorator as seen wi
204
208
@Args('id') id: string
205
209
```
206
210
207
-
However, in this case, the `number` type is used, and it presents a challenge. The `number` type doesn't give us enough information about the expected GraphQL representation (e.g., `Int` vs. `Float`). Thus we have to **explicitly** pass the type reference.
211
+
However, in this case, the `number` type is used, and it presents a challenge. The `number` TypeScript type doesn't give us enough information about the expected GraphQL representation (e.g., `Int` vs. `Float`). Thus we have to **explicitly** pass the type reference.
208
212
209
213
Query handler methods can take multiple arguments. Let's imagine that we want to fetch an author based on its `firstName` and `lastName`. In this case, we can call `@Args` twice:
0 commit comments