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
> warning **Warning** This chapter applies only to the code first approach.
4
+
5
+
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. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.
6
+
7
+
> info **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.
8
+
9
+
#### Overview
10
+
11
+
The GraphQL plugin will automatically:
12
+
13
+
- annotate all input object, object type and args classes properties with `@Field` unless `@HideField` is used
14
+
- set the `nullable` property depending on the question mark (e.g. `name?: string` will set `nullable: true`)
15
+
- set the `type` property depending on the type (supports arrays as well)
16
+
17
+
Please, note that your filenames **must have** one of the following suffixes in order to be analyzed by the plugin: `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` (e.g., `author.entity.ts`). If you are using a different suffix, you can adjust the plugin's behavior by specifying the `typeFileNameSuffix` option (see below).
18
+
19
+
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:
20
+
21
+
```typescript
22
+
@@filename(authors/models/author.model)
23
+
@ObjectType()
24
+
exportclassAuthor {
25
+
@Field(type=>Int)
26
+
id:number;
27
+
28
+
@Field({ nullable: true })
29
+
firstName?:string;
30
+
31
+
@Field({ nullable: true })
32
+
lastName?:string;
33
+
34
+
@Field(type=> [Post])
35
+
posts:Post[];
36
+
}
37
+
```
38
+
39
+
While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.
40
+
41
+
Now, with the GraphQL plugin enabled, the above class definition can be declared simply:
42
+
43
+
```typescript
44
+
@@filename(authors/models/author.model)
45
+
@ObjectType()
46
+
exportclassAuthor {
47
+
@Field(type=>Int)
48
+
id:number;
49
+
firstName?:string;
50
+
lastName?:string;
51
+
posts:Post[];
52
+
}
53
+
```
54
+
55
+
The plugin adds appropriate decorators on-the-fly based on the **Abstract Syntax Tree**. Thus, you won't have to struggle with `@Field` decorators scattered throughout the code.
56
+
57
+
> info **Hint** The plugin will automatically generate any missing swagger properties, but if you need to override them, simply set them explicitly via `@Field()`.
58
+
59
+
To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/cli/overview)) and add the following `plugins` configuration:
60
+
61
+
```javascript
62
+
{
63
+
"collection":"@nestjs/schematics",
64
+
"sourceRoot":"src",
65
+
"compilerOptions": {
66
+
"plugins": ["@nestjs/graphql/plugin"]
67
+
}
68
+
}
69
+
```
70
+
71
+
You can use the `options` property to customize the behavior of the plugin.
72
+
73
+
```javascript
74
+
"plugins": [
75
+
{
76
+
"name":"@nestjs/graphql/plugin",
77
+
"options": {
78
+
"typeFileNameSuffix": [".input.ts", ".args.ts"]
79
+
}
80
+
}
81
+
]
82
+
```
83
+
84
+
The `options` property has to fulfill the following interface:
Copy file name to clipboardExpand all lines: content/graphql/mutations.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -39,7 +39,7 @@ export class UpvotePostInput {
39
39
}
40
40
```
41
41
42
-
> info **Hint** The `@InputType()` decorator takes an options object as an argument, so you can, for example, specify the input type's description. Note that, due to TypeScript's metadata reflection system limitations, you must either use the `@Field` decorator to manually indicate a type, or use a [CLI plugin](/graphql/resolvers#cli-plugin).
42
+
> info **Hint** The `@InputType()` decorator takes an options object as an argument, so you can, for example, specify the input type's description. Note that, due to TypeScript's metadata reflection system limitations, you must either use the `@Field` decorator to manually indicate a type, or use a [CLI plugin](/graphql/cli-plugin).
> info **Hint** TypeScript's metadata reflection system has several limitations which make it impossible, for instance, to 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 to provide metadata about each field's GraphQL type and optionality, or use a [CLI plugin](/graphql/resolvers#cli-plugin) to generate these for us.
47
+
> info **Hint** TypeScript's metadata reflection system has several limitations which make it impossible, for instance, to 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 to provide metadata about each field's GraphQL type and optionality, or use a [CLI plugin](/graphql/cli-plugin) to generate these for us.
48
48
49
49
The `Author` object type, like any class, is made of a collection of fields, with each field declaring a type. A field's type corresponds to a [GraphQL type](https://graphql.org/learn/schema/). A field's GraphQL type can be either another object type or a scalar type. A GraphQL scalar type is a primitive (like `ID`, `String`, `Boolean`, or `Int`) that resolves to a single value.
50
50
@@ -294,7 +294,7 @@ class GetAuthorArgs {
294
294
}
295
295
```
296
296
297
-
> info **Hint** Again, due to TypeScript's metadata reflection system limitations, it's required to either use the `@Field` decorator to manually indicate type and optionality, or use a [CLI plugin](/graphql/resolvers#cli-plugin).
297
+
> info **Hint** Again, due to TypeScript's metadata reflection system limitations, it's required to either use the `@Field` decorator to manually indicate type and optionality, or use a [CLI plugin](/graphql/cli-plugin).
298
298
299
299
This will result in generating the following part of the GraphQL schema in SDL:
300
300
@@ -315,10 +315,10 @@ Base `@ArgsType()` class:
315
315
```typescript
316
316
@ArgsType()
317
317
classPaginationArgs {
318
-
@Field(type => Int)
318
+
@Field((type) => Int)
319
319
offset: number = 0;
320
320
321
-
@Field(type => Int)
321
+
@Field((type) => Int)
322
322
limit: number = 10;
323
323
}
324
324
```
@@ -342,7 +342,7 @@ The same approach can be taken with `@ObjectType()` objects. Define generic prop
342
342
```typescript
343
343
@ObjectType()
344
344
classCharacter {
345
-
@Field(type=>Int)
345
+
@Field((type)=>Int)
346
346
id:number;
347
347
348
348
@Field()
@@ -366,7 +366,7 @@ You can use inheritance with a resolver as well. You can ensure type safety by c
366
366
function BaseResolver<TextendsType<unknown>>(classRef:T):any {
@@ -411,22 +411,22 @@ import { Type } from '@nestjs/common';
411
411
export function Paginated<T>(classRef: Type<T>) {
412
412
@ObjectType(`${classRef.name}Edge`)
413
413
abstractclassEdgeType {
414
-
@Field(type => String)
414
+
@Field((type) => String)
415
415
cursor: string;
416
416
417
-
@Field(type => classRef)
417
+
@Field((type) => classRef)
418
418
node: T;
419
419
}
420
420
421
421
@ObjectType({ isAbstract: true })
422
422
abstractclassPaginatedType {
423
-
@Field(type => [EdgeType], { nullable: true })
423
+
@Field((type) => [EdgeType], { nullable: true })
424
424
edges: EdgeType[];
425
425
426
-
@Field(type => [classRef], { nullable: true })
426
+
@Field((type) => [classRef], { nullable: true })
427
427
nodes: T[];
428
428
429
-
@Field(type => Int)
429
+
@Field((type) => Int)
430
430
totalCount: number;
431
431
432
432
@Field()
@@ -663,113 +663,3 @@ export class AuthorsModule {}
663
663
```
664
664
665
665
> 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.
666
-
667
-
/////// MAYBE LET'S CREATE A SEPARATE CHAPTER(PAGE) FOR THIS? [CLI plugin]
668
-
669
-
#### CLI Plugin
670
-
671
-
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. However, some of these constraints can be addressed at compilation time. Nest provides a plugin that enhances the TypeScript compilation process to reduce the amount of boilerplate code required.
672
-
673
-
> warning **Hint** This plugin is **opt-in**. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.
674
-
675
-
The GraphQL plugin will automatically:
676
-
677
-
- annotate all input object, object type and args classes properties with `@Field` unless `@HideField` is used
678
-
- set the `nullable` property depending on the question mark (e.g. `name?: string` will set `nullable: true`)
679
-
- set the `type` property depending on the type (supports arrays as well)
680
-
681
-
Please, note that your filenames **must have** one of the following suffixes in order to be analyzed by the plugin: `['.input.ts', '.args.ts', '.entity.ts', '.model.ts']` (e.g., `author.entity.ts`). If you are using a different suffix, you can adjust the plugin's behavior by specifying the `typeFileNameSuffix` option (see below).
682
-
683
-
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:
684
-
685
-
```typescript
686
-
@@filename(authors/models/author.model)
687
-
@ObjectType()
688
-
exportclassAuthor {
689
-
@Field(type=>Int)
690
-
id:number;
691
-
692
-
@Field({ nullable: true })
693
-
firstName?:string;
694
-
695
-
@Field({ nullable: true })
696
-
lastName?:string;
697
-
698
-
@Field(type=> [Post])
699
-
posts:Post[];
700
-
}
701
-
```
702
-
703
-
While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.
704
-
705
-
Now, with the GraphQL plugin enabled, the above class definition can be declared simply:
706
-
707
-
```typescript
708
-
@@filename(authors/models/author.model)
709
-
@ObjectType()
710
-
exportclassAuthor {
711
-
@Field(type=>Int)
712
-
id:number;
713
-
firstName?:string;
714
-
lastName?:string;
715
-
posts:Post[];
716
-
}
717
-
```
718
-
719
-
The plugin adds appropriate decorators on-the-fly based on the **Abstract Syntax Tree**. Thus, you won't have to struggle with `@Field` decorators scattered throughout the code.
720
-
721
-
> warning **Hint** The plugin will automatically generate any missing swagger properties, but if you need to override them, simply set them explicitly via `@Field()`.
722
-
723
-
To enable the plugin, open `nest-cli.json` (if you use [Nest CLI](/cli/overview)) and add the following `plugins` configuration:
724
-
725
-
```javascript
726
-
{
727
-
"collection":"@nestjs/schematics",
728
-
"sourceRoot":"src",
729
-
"compilerOptions": {
730
-
"plugins": ["@nestjs/graphql/plugin"]
731
-
}
732
-
}
733
-
```
734
-
735
-
You can use the `options` property to customize the behavior of the plugin.
736
-
737
-
```javascript
738
-
"plugins": [
739
-
{
740
-
"name":"@nestjs/graphql/plugin",
741
-
"options": {
742
-
"typeFileNameSuffix": [".input.ts", ".args.ts"]
743
-
}
744
-
}
745
-
]
746
-
```
747
-
748
-
The `options` property has to fulfill the following interface:
Copy file name to clipboardExpand all lines: content/graphql/schema-generator.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,6 +17,8 @@ async function generateSchema() {
17
17
18
18
> info **Hint** The `GraphQLSchemaBuilderModule` and `GraphQLSchemaFactory` are imported from the `@nestjs/graphql` package. The `printSchema` function is imported from the `graphql` package.
19
19
20
+
#### Usage
21
+
20
22
The `gqlSchemaFactory.create()` method takes an array of resolver class references. For example:
-`skipCheck`: ignore schema validation; boolean, defaults to `false`
40
-
-`orphanedTypes`: list of classes that are not explicitly referenced (not part of the object graph) to be generated. Normally, if a class is declared but isn't otherwise referenced in the graph, it's omitted. The property value is an array of class references.
41
-
42
+
-`orphanedTypes`: list of classes that are not explicitly referenced (not part of the object graph) to be generated. Normally, if a class is declared but isn't otherwise referenced in the graph, it's omitted. The property value is an array of class references.
0 commit comments