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/quick-start.md
+10-8Lines changed: 10 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ And depending on what you use (Express or Fastify), you need to install `apollo-
16
16
17
17
#### Overview
18
18
19
-
Nest offers two ways of building GraphQL applications, the **schema first** and the **code first** methods.
19
+
Nest offers two ways of building GraphQL applications, the **code first** and the **schema first** methods.
20
20
21
21
In the **code first** approach, you use decorators and TypeScript classes to generate the corresponding GraphQL schema. This approach is useful if you prefer to work exclusively with TypeScript and avoid context switching between language syntaxes.
22
22
@@ -36,7 +36,7 @@ import { GraphQLModule } from '@nestjs/graphql';
36
36
GraphQLModule.forRoot({}),
37
37
],
38
38
})
39
-
exportclassApplicationModule {}
39
+
exportclassAppModule {}
40
40
```
41
41
42
42
The `forRoot()` method takes an options object as an argument. These options are passed through to the underlying Apollo instance (read more about available settings [here](https://www.apollographql.com/docs/apollo-server/v2/api/apollo-server.html#constructor-options-lt-ApolloServer-gt)). For example, if you want to disable the `playground` and turn off `debug` mode, pass the following options:
@@ -54,16 +54,18 @@ import { GraphQLModule } from '@nestjs/graphql';
54
54
}),
55
55
],
56
56
})
57
-
exportclassApplicationModule {}
57
+
exportclassAppModule {}
58
58
```
59
59
60
60
As mentioned, these options will be forwarded to the `ApolloServer` constructor.
61
61
62
62
<app-banner-enterprise></app-banner-enterprise>
63
63
64
-
#### Playground
64
+
#### GraphQL playground
65
65
66
-
The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. With your application running in the background, open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You should see the GraphQL playground, as shown below.
66
+
The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. To see the playground running, you need a basic GraphQL server configured and running. To see it now, you can install the [working example here](https://github.com/nestjs/nest/tree/master/sample/12-graphql-schema-first). Alternatively, if you're following along with these code samples, once you've complete the steps in the [Resolvers chapter](/graphql/resolvers-map), you can access the playground.
67
+
68
+
With that in place, and with your application running in the background, open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You should see the GraphQL playground, as shown below.
67
69
68
70
<figure>
69
71
<imgsrc="/assets/playground.png"alt="" />
@@ -111,9 +113,9 @@ GraphQLModule.forRoot({
111
113
}),
112
114
```
113
115
114
-
The `typePaths` property indicates where the `GraphQLModule` should look for GraphQL files. These files will be combined in memory; this allows you to split your schemas into several files and locate them near their resolvers.
116
+
The `typePaths` property indicates where the `GraphQLModule` should look for GraphQL SDL schema definition files. These files will be combined in memory; this allows you to split your schemas into several files and locate them near their resolvers.
115
117
116
-
Creating GraphQL types and corresponding TypeScript definitions is redundant and tedious. It leaves us without a single source of truth -- each change made within SDL forces us to adjust interfaces as well. To address this, the `@nestjs/graphql` package can automatically generate TS definitions from the abstract syntax tree (AST). To enable this feature, add the `definitions` options property when configuring the `GraphQLModule`.
118
+
You will typically need to have TypeScript definitions (classes and interfaces) that correspond to GraphQL types. Creating the corresponding TypeScript definitions is redundant and tedious. It leaves us without a single source of truth -- each change made within SDL forces us to adjust TypeScript definitions as well. To address this, the `@nestjs/graphql` package can automatically generate TypeScript definitions from the abstract syntax tree ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)). To enable this feature, add the `definitions` options property when configuring the `GraphQLModule`.
117
119
118
120
```typescript
119
121
GraphQLModule.forRoot({
@@ -124,7 +126,7 @@ GraphQLModule.forRoot({
124
126
}),
125
127
```
126
128
127
-
The path property of the `definitions` object (e.g., `src/graphql.ts` above) indicates where to save TypeScript output. By default, all types are generated as interfaces. To generate classes instead, specify the `outputAs` property with a value of `'class'`.
129
+
The path property of the `definitions` object (e.g., `src/graphql.ts` above) indicates where to save generated TypeScript output. By default, all types are generated as interfaces. To generate classes instead, specify the `outputAs` property with a value of `'class'`.
Copy file name to clipboardExpand all lines: content/graphql/resolvers-map.md
+28-11Lines changed: 28 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
### Resolvers
2
2
3
-
Resolvers provide the instructions for turning a [GraphQL](https://graphql.org/) operation (a query, mutation, or subscription) into data. They either return the same type of data we specify in our schema or a promise for that data. Typically, you create a resolvers map manually. The `@nestjs/graphql` package, on the other hand, generates a resolvers map automatically using the metadata provided by the decorators. To demonstrate the library basics, we'll create a simple authors API.
3
+
Resolvers provide the instructions for turning a [GraphQL](https://graphql.org/) operation (a query, mutation, or subscription) into data. They return the same shape of data we specify in our schema -- either synchronously or as a promise that resolves to a result of that shape. Typically, you create a **resolvers map** manually. The `@nestjs/graphql` package, on the other hand, generates a resolvers map automatically using the metadata provided by the decorators. To demonstrate the library basics, we'll create a simple authors API.
4
4
5
5
#### Code first
6
6
@@ -214,7 +214,7 @@ You may also notice that such classes play very well with the `ValidationPipe` (
214
214
215
215
#### Schema first
216
216
217
-
Asmentionedinthe [previous](/graphql/quick-start) chapter, intheschema first approach we manually define our types in SDL (read [more](http://graphql.org/learn/schema/#type-language)).
217
+
Asmentionedinthe [previous](/graphql/quick-start) chapter, intheschema first approach we manually define our types in SDL (read [more](http://graphql.org/learn/schema/#type-language)). Consider the following type definitions:
218
218
219
219
```graphql
220
220
type Author {
@@ -235,7 +235,7 @@ type Query {
235
235
}
236
236
```
237
237
238
-
OurGraphQLschemacontains a single exposed query - `author(id: Int!): Author`. Now, let's create an `AuthorResolver` class.
238
+
Thisschemaexposes a single query - `author(id: Int!): Author`. Let's create an `AuthorResolver` class that resolves author queries:
239
239
240
240
```typescript
241
241
@Resolver('Author')
@@ -260,9 +260,9 @@ export class AuthorResolver {
260
260
261
261
> info **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.
262
262
263
-
> 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 resolvers can interact with other providers.
263
+
> 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.
264
264
265
-
The `@Resolver()` decorator does not affect queries and mutations (neither `@Query()` nor `@Mutation()` decorators). It only informs Nest that each `@ResolveField()` inside this particular class has a parent, which is an `Author` type in this case (`Author.posts` relation). Basically, instead of setting `@Resolver()` at the top of the class, this can be done close to the method:
265
+
The `@Resolver()` decorator is used to inform Nest that each `@ResolveField()`method inside the class has a parent (the `Author` type in this case). The `@Resolver()` decorator **does not** affect queries (`@Query()` decorator) or mutations (`@Mutation()` decorator). Alternatively, instead of setting `@Resolver()` at the top of the class, this can be done for each method:
> warning **Warning** Using the `@Resolver` decorator at the method-levelis not supported with the **code first** approach.
276
+
In this case (`@Resolver()` decorator at the methodlevel), if you have multiple `@ResolveField()` decorators inside a class, you must add `@Resolver()` to all of them. This is not considered the best practice (as it creates extra overhead).
277
277
278
-
However, if you have multiple`@ResolveField()` decorators inside one class, you must add `@Resolver()` to all of them, which is not necessarily a good practice (as it creates extra overhead).
278
+
> warning **Warning** Using the`@Resolver` decorator at the method level is not supported with the **code first** approach.
279
279
280
-
Conventionally, we would use something like `getAuthor()` or `getPosts()` as method names. We can easily do this by passing the real names as arguments of the decorator.
280
+
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:
281
+
282
+
```typescript
283
+
@Query()
284
+
asyncauthor(@Args('id') id: number) {
285
+
returnthis.authorsService.findOneById(id);
286
+
}
287
+
```
288
+
289
+
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):
290
+
291
+
```graphql
292
+
typeQuery {
293
+
author(id: Int!): Author
294
+
}
295
+
```
296
+
297
+
Conventionally, wewouldprefertodecouplethese, usingnameslike `getAuthor()` or `getPosts()` forourresolvermethods. Wecaneasilydothisbypassingthemappingnamesasargumentsofthedecorator, asshownbelow
281
298
282
299
```typescript
283
300
@Resolver('Author')
@@ -323,7 +340,7 @@ export abstract class IQuery {
323
340
}
324
341
```
325
342
326
-
Generating classes (instead of interfaces) allows you to use **decorators** in combination with the schema first approach, which makes them extremely useful for validation purposes (read [more](/techniques/validation)). For example:
343
+
Generating classes (instead of the default technique of generating interfaces) allows you to use declarative validation **decorators** in combination with the schema first approach, which is an extremely useful technique (read [more](/techniques/validation)). For example, you could add these `class-validator` decorators to the generated `CreatePostInput` class as shown below:
@@ -386,7 +403,7 @@ These arguments have the following meanings:
386
403
387
404
#### Module
388
405
389
-
Once we're done with the above steps, we have to provide the `AuthorResolver` somewhere (for dependency injection). For example, we can do this in the newly created `AuthorsModule`.
406
+
Once we're done with the above steps, we have to provide the `AuthorResolver` somewhere (list it as a `provider` in some module, for dependency injection). For example, we can do this in an `AuthorsModule`, which can also provide other services needed in this context.
390
407
391
408
```typescript
392
409
@Module({
@@ -412,7 +429,7 @@ The GraphQL plugin will automatically:
412
429
- set the `nullable` property depending on the question mark (e.g. `name?: string` will set `nullable: true`)
413
430
- set the `type` property depending on the type (supports arrays as well)
414
431
415
-
Please, note that your filenames **must have** one of the following suffixes: `['.input.ts', '.args.ts', '.entity.ts']` (e.g., `author.entity.ts`) in order to be analysed by the plugin.
432
+
Please, note that your filenames **must have** one of the following suffixes: `['.input.ts', '.args.ts', '.entity.ts']` (e.g., `author.entity.ts`) in order to be analyzed by the plugin.
416
433
417
434
Previously, you had to duplicate a lot of code to let the package know how your type should be declared in GraphQL. For example, you could define a simple `Author` class as follows:
0 commit comments