Skip to content

Commit a0caa66

Browse files
committed
updates
1 parent e197583 commit a0caa66

File tree

2 files changed

+31
-17
lines changed

2 files changed

+31
-17
lines changed

content/graphql/quick-start.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ As mentioned, these options will be forwarded to the `ApolloServer` constructor.
6363

6464
#### GraphQL playground
6565

66-
The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. To access the playground, you need a basic GraphQL server configured and running. To see it now, you can install and build 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.
66+
The playground is a graphical, interactive, in-browser GraphQL IDE, available by default on the same URL as the GraphQL server itself. To access the playground, you need a basic GraphQL server configured and running. To see it now, you can install and build the [working example here](https://github.com/nestjs/nest/tree/master/sample/23-graphql-code-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.
6767

6868
With that in place, and with your application running in the background, you can then open your web browser and navigate to `http://localhost:3000/graphql` (host and port may vary depending on your configuration). You will then see the GraphQL playground, as shown below.
6969

content/graphql/resolvers-map.md

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type Author {
2222
In this case, using the code first approach, we define schemas using TypeScript classes and using TypeScript decorators to annotate the fields of those classes. The equivalent of the above SDL in the code first approach is:
2323

2424
```typescript
25+
@@filename(authors/models/author.model)
2526
import { Field, Int, ObjectType } from '@nestjs/graphql';
2627
import { Post } from './post';
2728

@@ -124,8 +125,9 @@ type Post {
124125
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.
125126

126127
```typescript
128+
@@filename(authors/authors.resolver)
127129
@Resolver(of => Author)
128-
export class AuthorResolver {
130+
export class AuthorsResolver {
129131
constructor(
130132
private authorsService: AuthorsService,
131133
private postsService: PostsService,
@@ -148,7 +150,7 @@ export class AuthorResolver {
148150
149151
> 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.
150152
151-
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.
153+
In the example above, we created the `AuthorsResolver` 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.
152154

153155
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.
154156

@@ -173,11 +175,14 @@ type Query {
173175
}
174176
```
175177

178+
> info **Hint** Learn more about GraphQL queries [here](http://graphql.org/learn/queries/).
179+
176180
Conventionally, we prefer to decouple these names; for example, we prefer to use a name like `getAuthor()` for our query handler method, but still use `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:
177181

178182
```typescript
183+
@@filename(authors/authors.resolver)
179184
@Resolver(of => Author)
180-
export class AuthorResolver {
185+
export class AuthorsResolver {
181186
constructor(
182187
private authorsService: AuthorsService,
183188
private postsService: PostsService,
@@ -206,10 +211,10 @@ type Query {
206211

207212
The `@Query()` decorator's options object (where we pass `{{ '{' }}name: 'author'{{ '}' }}` above) accepts a number of keys:
208213

209-
- name: name of the query; a `string`
210-
- description: a description that will be used to generate GraphQL schema documentation (e.g., in GraphQL playground); a `string`
211-
- deprecationReason: sets query metadata to show the query as deprecated (e.g., in GraphQL playground); a `string`
212-
- nullable: whether the query can return a null data response; `boolean` or `'items'` or `'itemsAndList'` (see above for details of `'items'` and `'itemsAndList'`)
214+
- `name`: name of the query; a `string`
215+
- `description`: a description that will be used to generate GraphQL schema documentation (e.g., in GraphQL playground); a `string`
216+
- `deprecationReason`: sets query metadata to show the query as deprecated (e.g., in GraphQL playground); a `string`
217+
- `nullable`: whether the query can return a null data response; `boolean` or `'items'` or `'itemsAndList'` (see above for details of `'items'` and `'itemsAndList'`)
213218

214219
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:
215220

@@ -236,9 +241,10 @@ With inline `@Args()` calls, code like the example above becomes bloated. Instea
236241
@Args() args: GetAuthorArgs
237242
```
238243

239-
Create the `GetAuthorArgs()` class using `@ArgsType()` as shown below:
244+
Create the `GetAuthorArgs` class using `@ArgsType()` as shown below:
240245

241246
```typescript
247+
@@filename(authors/dto/get-author.args)
242248
import { MinLength } from 'class-validator';
243249
import { Field, ArgsType } from '@nestjs/graphql';
244250

@@ -292,11 +298,16 @@ type Query {
292298

293299
### Schema first resolver
294300

295-
The schema above exposes a single query - `author(id: Int!): Author`. Let's now create an `AuthorResolver` class that resolves author queries:
301+
The schema above exposes a single query - `author(id: Int!): Author`.
302+
303+
> info **Hint** Learn more about GraphQL queries [here](http://graphql.org/learn/queries/).
304+
305+
Let's now create an `AuthorsResolver` class that resolves author queries:
296306

297307
```typescript
308+
@@filename(authors/authors.resolver)
298309
@Resolver('Author')
299-
export class AuthorResolver {
310+
export class AuthorsResolver {
300311
constructor(
301312
private authorsService: AuthorsService,
302313
private postsService: PostsService,
@@ -356,8 +367,9 @@ type Query {
356367
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 name as an argument to the decorator, as shown below:
357368

358369
```typescript
370+
@@filename(authors/authors.resolver.ts)
359371
@Resolver('Author')
360-
export class AuthorResolver {
372+
export class AuthorsResolver {
361373
constructor(
362374
private authorsService: AuthorsService,
363375
private postsService: PostsService,
@@ -381,6 +393,7 @@ export class AuthorResolver {
381393
Assuming that we use the schema first approach and have enabled the typings generation feature (with `outputAs: 'class'` as shown in the [previous](/graphql/quick-start) chapter), once you run the application it will generate the following file (in the location you specified in the `GraphQLModule.forRoot()` method. For example, in `src/graphql.ts`)
382394

383395
```typescript
396+
@@filename(graphql.ts)
384397
export class Author {
385398
id: number;
386399
firstName?: string;
@@ -426,7 +439,7 @@ export class CreatePostInput extends Post {
426439
}
427440
```
428441

429-
#### GraphQL resolver argument decorators
442+
#### GraphQL argument decorators
430443

431444
We can access the standard GraphQL resolver arguments using dedicated decorators. Below is a comparison of the Nest decorators and the plain Apollo parameters they represent.
432445

@@ -464,20 +477,19 @@ These arguments have the following meanings:
464477

465478
Once we're done with the above steps, we have declaratively specified all the information needed by the `GraphQLModule` to generate a resolver map. The `GraphQLModule` uses reflection to introspect the meta data provided via the decorators, and transforms classes into the correct resolver map automatically.
466479

467-
The only other thing you need to take care of is to **provide** (i.e., list as a `provider` in some module) the resolver class(es) (`AuthorResolver`), and importing the module (`AuthorsModule`) somewhere, so Nest will be able to utilize it.
480+
The only other thing you need to take care of is to **provide** (i.e., list as a `provider` in some module) the resolver class(es) (`AuthorsResolver`), and importing the module (`AuthorsModule`) somewhere, so Nest will be able to utilize it.
468481

469482
For example, we can do this in an `AuthorsModule`, which can also provide other services needed in this context. Be sure to import `AuthorsModule` somewhere (e.g., in the root module, or some other module imported by the root module).
470483

471484
```typescript
485+
@@filename(authors/authors.module)
472486
@Module({
473487
imports: [PostsModule],
474-
providers: [AuthorsService, AuthorResolver],
488+
providers: [AuthorsService, AuthorsResolver],
475489
})
476490
export class AuthorsModule {}
477491
```
478492

479-
> info **Hint** Learn more about GraphQL queries [here](http://graphql.org/learn/queries/).
480-
481493
> info **Hint** It is helpful to organize your code by your so-called **domain model** (similar to the way you would organize entry points in a REST API). In this approach, keep your models (`ObjectType` classes), resolvers and services together within a Nest module representing the domain model. Keep all of these components in a single folder per module. When you do this, and use the [Nest CLI](/cli/overview) to generate each element, Nest will wire all of these parts together (locating files in appropriate folders, generating entries in `provider` and `imports` arrays, etc.) automatically for you.
482494
483495
#### CLI Plugin
@@ -497,6 +509,7 @@ Please, note that your filenames **must have** one of the following suffixes: `[
497509
With what we've learned so far, you have 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:
498510

499511
```typescript
512+
@@filename(authors/models/author.model)
500513
@ObjectType()
501514
export class Author {
502515
@Field(type => Int)
@@ -518,6 +531,7 @@ While not a significant issue with medium-sized projects, it becomes verbose & h
518531
Now, with the GraphQL plugin enabled, the above class definition can be declared simply:
519532

520533
```typescript
534+
@@filename(authors/models/author.model)
521535
@ObjectType()
522536
export class Author {
523537
@Field(type => Int)

0 commit comments

Comments
 (0)