Skip to content

Commit a1eb1d9

Browse files
committed
updates
1 parent bd62f73 commit a1eb1d9

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

content/graphql/resolvers-map.md

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ type Post {
110110

111111
### Code first resolver
112112

113-
At this point, we've defined the objects that exist in our data graph, but clients don't yet have a way to interact with those objects. To address that, we need to define a resolver class:
113+
At this point, we've defined the objects that exist in our data graph, but clients don't yet have a way to interact with those objects. To address that, we need to define a resolver class. We'll start with the example below.
114114

115115
```typescript
116116
@Resolver(of => Author)
@@ -137,11 +137,13 @@ export class AuthorResolver {
137137
138138
> 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.
139139
140-
In the example above, we created the `AuthorResolver` which defines one query and one field resolver function. We can define multiple `@Query()` resolver functions, and they will be aggregated into a single Query type definition in the generated SDL and the appropriate keys 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.
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.
141141

142-
Note that to create a resolver, we must annotate the class with the `@Resolver()` decorator. The argument passed in to the `@Resolver()` decorator is optional, but since we have also defined a field resolver (for the `posts` property of the `Author` object type), it's required to indicate which class is a parent for this particular field resolver (`Author.posts` relation). In addition, we defined a first query to get the author object based on the `id` sent in the request. Queries enable clients to fetch data, but not to **modify** data. To specify that the method is a query handler, use the `@Query()` decorator.
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.
143143

144-
In the above examples, the `@Query()` and `@ResolveField()` decorators are associated with the types based on the method name. For example, consider the following construction from the example above:
144+
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+
146+
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:
145147

146148
```typescript
147149
@Query(returns => Author)
@@ -150,15 +152,15 @@ In the above examples, the `@Query()` and `@ResolveField()` decorators are assoc
150152
}
151153
```
152154

153-
This generates the resolver map entry for the author query in our schema (because the method name `author` matches the `author` field in the `Query` type):
155+
This generates the following resolver map entry for the author query in our schema (the query type entry uses the same name as the method name):
154156

155157
```graphql
156158
type Query {
157159
author(id: Int!): Author
158160
}
159161
```
160162

161-
Conventionally, we would prefer to decouple these, using names like `getAuthor()` or `getPosts()` for our resolver methods. We can easily do this by passing the mapping names as arguments of the decorator, as shown below
163+
Conventionally, we prefer to decouple these names; for example, using a name like `getAuthor()` for our query handler method, but still using `author` for our query type name. The same applies to our field resolvers. We can easily do this by passing the mapping names as arguments of the `@Query()` and `@ResolveField()` decorators, as shown below:
162164

163165
```typescript
164166
@Resolver(of => Author)
@@ -181,23 +183,30 @@ export class AuthorResolver {
181183
}
182184
```
183185

184-
The `AuthorResolver` resolver will result in generating the following part of the GraphQL schema in SDL:
186+
The `AuthorResolver` resolver above will result in generating the following part of the GraphQL schema in SDL:
185187

186188
```graphql
187189
type Query {
188190
author(id: Int!): Author
189191
}
190192
```
191193

192-
Usually you won't have to pass an object into the `@Args()` decorator as with the `getAuthor()` method above. For example, if an identifier's type is string, the following construction would be sufficient:
194+
The options object (where we pass `{{ '{' }}name: 'author'{{ '}' }}` above) accepted by the `@Query()` decorator accepts a number of keys:
195+
196+
- name: name of the query; a `string`
197+
- description: a description that will be used to generate GraphQL schema documentation (e.g. in GraphQL playground); a `string`
198+
- deprecationReason: sets query metadata to show the query as deprecated (e.g., in GraphQL playground); a `string`
199+
- nullable: whether the query can return a null data response; `boolean` or `'items'` or `'itemsAndList'` (see above for details of `'items'` and `'itemsAndList'`)
200+
201+
Usually you won't have to pass an object into the `@Args()` decorator as seen with the `getAuthor()` method above. For example, if an identifier's type is string, the following construction is sufficient:
193202

194203
```typescript
195204
@Args('id') id: string
196205
```
197206

198-
However, the `number` type doesn't give us enough information about the expected GraphQL representation (`Int` vs. `Float`). Thus we have to **explicitly** pass the type reference.
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.
199208

200-
In addition, all queries 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:
209+
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:
201210

202211
```typescript
203212
getAuthor(
@@ -206,9 +215,9 @@ getAuthor(
206215
) {}
207216
```
208217

209-
> info **Hint** Note that we can pass a second argument to the `@Args()` decorator, which is an options object. The options object allows us to specify a default value, description, deprecation reason, or if a field is nullable.
218+
> info **Hint** Note that we can pass a second argument to the `@Args()` decorator, which is an options object. The options object allows us to specify a default value (`'defaultValue'` key), description (`'description'` key, ), deprecation reason (`'deprecationReason'` key), or if a field is nullable (`'nullable'` key).
210219
211-
With inline `@Args()` calls, the code becomes bloated. Instead, you can create a dedicated `GetAuthorArgs` class:
220+
With inline `@Args()` calls, code like the example above becomes bloated. Instead, you can create a dedicated `GetAuthorArgs` class using the `@ArgsType()` decorator.
212221

213222
```typescript
214223
@Args() args: GetAuthorArgs
@@ -221,7 +230,7 @@ import { MinLength } from 'class-validator';
221230
import { Field, ArgsType } from '@nestjs/graphql';
222231

223232
@ArgsType()
224-
class GetByIdArgs {
233+
class GetAuthorArgs {
225234
@Field({ nullable: true })
226235
firstName?: string;
227236

0 commit comments

Comments
 (0)