Skip to content

Commit bd62f73

Browse files
committed
updates
1 parent a1a6710 commit bd62f73

File tree

2 files changed

+49
-18
lines changed

2 files changed

+49
-18
lines changed

content/graphql/quick-start.md

Lines changed: 2 additions & 2 deletions
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 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.
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 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.
6767

6868
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.
6969

@@ -89,7 +89,7 @@ To use the code first approach, start by adding the `autoSchemaFile` property to
8989

9090
```typescript
9191
GraphQLModule.forRoot({
92-
autoSchemaFile: 'schema.gql',
92+
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
9393
}),
9494
```
9595

content/graphql/resolvers-map.md

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ In the code first approach, we don't write GraphQL SDL by hand. Instead we use T
88

99
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.
1010

11+
In the schema first approach, we'd define such a schema with SDL like this:
12+
13+
```graphql
14+
type Author {
15+
id: Int!
16+
firstName: String
17+
lastName: String
18+
posts: [Post]
19+
}
20+
```
21+
22+
In the code first approach, on the other hand, we start by defining 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:
23+
1124
```typescript
1225
import { Field, Int, ObjectType } from '@nestjs/graphql';
1326
import { Post } from './post';
@@ -32,18 +45,15 @@ export class Author {
3245
3346
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.
3447

35-
The `Author` object type will result in generating the following part of the GraphQL schema in SDL:
48+
The above `Author` object type definition will generate the SDL we showed above.
3649

37-
```graphql
38-
type Author {
39-
id: Int!
40-
firstName: String
41-
lastName: String
42-
posts: [Post]
43-
}
44-
```
50+
The `@Field()` decorator accepts an optional function returning a type (e.g., `type => Int`), and optionally an object with the following keys:
4551

46-
The `@Field()` decorator allows specifying whether a field is nullable (each field is non-nullable by default), providing a type function, setting a description, or marking a field as deprecated:
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
55+
56+
It also accepts a type function. For example:
4757

4858
```typescript
4959
@Field({ description: `Book title`, deprecationReason: 'Not useful in v2 schema' })
@@ -52,7 +62,7 @@ title: string;
5262

5363
> info **Hint** You can also add a description to, or deprecate, the whole object type: `@ObjectType({{ '{' }} description: 'Author model' {{ '}' }})`.
5464
55-
When the field is an array, we must manually indicate the array type as shown below:
65+
When the field is an array, we must manually indicate the array type in the decorator type function, as shown below:
5666

5767
```typescript
5868
@Field(type => [Post])
@@ -68,7 +78,7 @@ To declare that the array's items (not the array itself) are nullable, set the `
6878
posts: Post[];
6979
```
7080

71-
> info **Hint** If both the array and its items are nullable, use the `'itemsAndList'` property instead.
81+
> info **Hint** If both the array and its items are nullable, set `nullable` to `'itemsAndList'` instead.
7282
7383
Now that the `Author` object type is created, let's define the `Post` object type.
7484

@@ -98,7 +108,9 @@ type Post {
98108
}
99109
```
100110

101-
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:
111+
### Code first resolver
112+
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:
102114

103115
```typescript
104116
@Resolver(of => Author)
@@ -123,11 +135,30 @@ export class AuthorResolver {
123135

124136
> info **Hint** All decorators (e.g., `@Resolver`, `@ResolveField`, `@Args`, etc.) are exported from the `@nestjs/graphql` package.
125137
126-
> 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.
138+
> 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+
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.
141+
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.
143+
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:
145+
146+
```typescript
147+
@Query(returns => Author)
148+
async author(@Args({ name: 'id', type: () => Int }) id: number) {
149+
return this.authorsService.findOneById(id);
150+
}
151+
```
127152

128-
In the example above, we created the `AuthorResolver` which defines one query and one field resolver. 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.
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):
154+
155+
```graphql
156+
type Query {
157+
author(id: Int!): Author
158+
}
159+
```
129160

130-
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.
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
131162

132163
```typescript
133164
@Resolver(of => Author)

0 commit comments

Comments
 (0)