CLI Plugin

Warning This chapter applies only to the code first approach.

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.

Hint This plugin is opt-in. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.

Overview

The GraphQL plugin will automatically:

  • annotate all input object, object type and args classes properties with @Field unless @HideField is used
  • set the nullable property depending on the question mark (e.g. name?: string will set nullable: true)
  • set the type property depending on the type (supports arrays as well)

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).

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:

authors/models/author.model.ts

  1. @ObjectType()
  2. export class Author {
  3. @Field(type => Int)
  4. id: number;
  5. @Field({ nullable: true })
  6. firstName?: string;
  7. @Field({ nullable: true })
  8. lastName?: string;
  9. @Field(type => [Post])
  10. posts: Post[];
  11. }

While not a significant issue with medium-sized projects, it becomes verbose & hard to maintain once you have a large set of classes.

By enabling the GraphQL plugin, the above class definition can be declared simply:

authors/models/author.model.ts

  1. @ObjectType()
  2. export class Author {
  3. @Field(type => Int)
  4. id: number;
  5. firstName?: string;
  6. lastName?: string;
  7. posts: Post[];
  8. }

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.

Hint The plugin will automatically generate any missing swagger properties, but if you need to override them, simply set them explicitly via @Field().

Using the CLI plugin

To enable the plugin, open nest-cli.json (if you use Nest CLI) and add the following plugins configuration:

  1. {
  2. "collection": "@nestjs/schematics",
  3. "sourceRoot": "src",
  4. "compilerOptions": {
  5. "plugins": ["@nestjs/graphql/plugin"]
  6. }
  7. }

You can use the options property to customize the behavior of the plugin.

  1. "plugins": [
  2. {
  3. "name": "@nestjs/graphql/plugin",
  4. "options": {
  5. "typeFileNameSuffix": [".input.ts", ".args.ts"]
  6. }
  7. }
  8. ]

The options property has to fulfill the following interface:

  1. export interface PluginOptions {
  2. typeFileNameSuffix?: string[];
  3. }
OptionDefaultDescription
typeFileNameSuffix[‘.input.ts’, ‘.args.ts’, ‘.entity.ts’, ‘.model.ts’]GraphQL types files suffix

If you don’t use the CLI but instead have a custom webpack configuration, you can use this plugin in combination with ts-loader:

  1. getCustomTransformers: (program: any) => ({
  2. before: [require('@nestjs/graphql/plugin').before({}, program)]
  3. }),