NestJS course Β· Module 11: Swagger and OpenAPI

CLI Plugin - The Automatic Scribe

3 min read
In this lesson8

Imagine that in the imperial chancellery you have a scribe who automatically documents every decree based on its content - you don't need to tell him what to write, he understands the document structure on his own. This is exactly how the @nestjs/swagger CLI Plugin works.

The Problem with Manual Documentation

Without the CLI Plugin, you have to manually add @ApiProperty() to every field in every DTO:

1// Without CLI Plugin - lots of repetitive code
2export class CreateLegionaryDto {
3  @ApiProperty({ description: 'Name of the legionary' })
4  name: string;
5
6  @ApiProperty({ description: 'Rank', required: false })
7  rank?: string;
8
9  @ApiProperty({ description: 'Experience' })
10  experience: number;
11
12  @ApiProperty({ description: 'Is active' })
13  isActive: boolean;
14}

CLI Plugin - Automatic Generation

The CLI Plugin analyzes TypeScript types and automatically generates Swagger metadata. A simple class is enough:

1// With CLI Plugin - clean code, automatic documentation
2export class CreateLegionaryDto {
3  /** Name of the legionary */
4  name: string;
5
6  /** Rank in the legion */
7  rank?: string;
8
9  /** Years of experience */
10  experience: number;
11
12  /** Whether the legionary is active */
13  isActive: boolean;
14}

The plugin automatically:

  • Recognizes field types (string, number, boolean)
  • Marks fields with ? as optional
  • Converts JSDoc comments into Swagger descriptions
  • Generates appropriate @ApiProperty() at compile time

Configuration in nest-cli.json

To enable the CLI Plugin, add the appropriate configuration in the nest-cli.json file:

1{
2  "collection": "@nestjs/schematics",
3  "sourceRoot": "src",
4  "compilerOptions": {
5    "deleteOutDir": true,
6    "plugins": [
7      {
8        "name": "@nestjs/swagger",
9        "options": {
10          "classValidatorShim": true,
11          "introspectComments": true,
12          "dtoFileNameSuffix": [".dto.ts", ".entity.ts"]
13        }
14      }
15    ]
16  }
17}

CLI Plugin Options

OptionDescriptionDefault
classValidatorShimAutomatically adds validation rules from class-validatortrue
introspectCommentsUses JSDoc comments as descriptionsfalse
dtoFileNameSuffixWhich files to analyze['.dto.ts', '.entity.ts']
controllerFileNameSuffixController file suffix'.controller.ts'
controllerKeyOfCommentComment key for controllers'description'

introspectComments - Comments as Documentation

When introspectComments is enabled, JSDoc comments become Swagger descriptions:

1export class LegionDto {
2  /**
3   * Unique legion name in the Empire
4   * @example 'Legio X Gemina'
5   */
6  name: string;
7
8  /**
9   * Stationing province
10   * @example 'Pannonia'
11   */
12  province: string;
13
14  /**
15   * Number of soldiers in the legion
16   * @example 5000
17   */
18  soldiers: number;
19}

The @example tag automatically generates an example value in Swagger UI.

classValidatorShim - Integration with Validation

When classValidatorShim is enabled, class-validator decorators affect Swagger documentation:

1import { IsString, IsNumber, IsOptional, Min, Max, IsEnum } from 'class-validator';
2
3export class CreateLegionaryDto {
4  /** Name of the legionary */
5  @IsString()
6  name: string;
7
8  /** Rank in the legion */
9  @IsEnum(LegionaryRank)
10  @IsOptional()
11  rank?: LegionaryRank;
12
13  /** Years of experience */
14  @IsNumber()
15  @Min(0)
16  @Max(40)
17  experience: number;
18}

The plugin automatically:

  • @IsOptional() marks the field as required: false
  • @IsEnum() generates the list of allowed values
  • @Min() / @Max() sets minimum / maximum
  • @IsString() confirms the string type

When to Still Use @ApiProperty?

The CLI Plugin does not replace all use cases of @ApiProperty(). You still need it for:

  • Nested types (type: () => AddressDto)
  • Arrays of objects (type: [LegionaryDto])
  • Complex examples
  • Overriding automatically generated descriptions

Practical Exercise

Configure the CLI Plugin and create a DTO with JSDoc comments:

Code for this lesson: src/nest-cli.config.ts
1// CLI Plugin configuration for @nestjs/swagger
2// This file presents the nest-cli.json configuration
3
4const nestCliConfig = {
5  collection: "@nestjs/schematics",
6  sourceRoot: "src",
7  compilerOptions: {
8    deleteOutDir: true,
9    plugins: [
10      {
11        name: "@nestjs/swagger",
12        options: {
13          // TODO: Enable classValidatorShim (true)
14          // TODO: Enable introspectComments (true)
15          // TODO: Set dtoFileNameSuffix to ['.dto.ts', '.entity.ts']
16        }
17      }
18    ]
19  }
20};
21
22console.log("=== nest-cli.json config ===");
23console.log(JSON.stringify(nestCliConfig, null, 2));
24
25// Example DTO with JSDoc comments (instead of @ApiProperty)
26class LegionaryDto {
27  /** Unique name of the legionary
28   * @example 'Marcus Aurelius'
29   */
30  name: string;
31
32  /** Rank in the legion hierarchy
33   * @example 'Centurio'
34   */
35  rank?: string;
36
37  /** Years of service in the legion
38   * @example 8
39   */
40  experience: number;
41
42  /** Whether the legionary is active in service
43   * @example true
44   */
45  isActive: boolean;
46}
47
48console.log("");
49console.log("With the CLI Plugin, JSDoc comments become Swagger descriptions");
50console.log("The @example tag generates example values");
51console.log("Fields with ? are automatically marked as optional");
52console.log("classValidatorShim integrates validation with the documentation");
53

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. What does the @nestjs/swagger CLI Plugin do?

  2. 2. What does the introspectComments option do in the @nestjs/swagger CLI Plugin?

These are 2 of 3 questions for this lesson. Solve the rest in the game.

Hands-on tasks in the game

  • Vertical ordering

    Order the steps for enabling the CLI Plugin from the configuration file to the result:

  • Code editor

    Add JSDoc comments with a description and @example to each DTO field

  • Horizontal ordering

    Arrange the elements of a JSDoc comment with the @example tag:

  • Click in order

    Arrange the plugin configuration elements in nest-cli.json from the outer key to the options:

  • Code editor

    Create SenatorResponseDto and CreateSenatorDto, then use them as the type in response decorators

Useful articles