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.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}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:
string, number, boolean)? as optional@ApiProperty() at compile timeTo 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}| Option | Description | Default | |--------|-------------|---------| |
classValidatorShim | Automatically adds validation rules from class-validator | true |
| introspectComments | Uses JSDoc comments as descriptions | false |
| dtoFileNameSuffix | Which files to analyze | ['.dto.ts', '.entity.ts'] |
| controllerFileNameSuffix | Controller file suffix | '.controller.ts' |
| controllerKeyOfComment | Comment key for controllers | 'description' |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.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 typeThe CLI Plugin does not replace all use cases of
@ApiProperty(). You still need it for:type: () => AddressDto)type: [LegionaryDto])Configure the CLI Plugin and create a DTO with JSDoc comments: