6

I'm researching the way on how to avoid to specify @ApiProperty() in each dto.

I know there is exist a way to create file nest-cli.json, and if you specify Promise<DTO> in your controller in nest-swagger it will produce the output dto from the route.

The structure looks like this:

nest-cli.json

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": [
      {
        "name": "@nestjs/swagger",
        "options": {
          "introspectComments": true
        }
      }
    ]
  }
}

controller.ts

@Get()
  async getMonitors (): Promise<OutputMonitorsDto> { // <-- Here is my outputDto
    return this.monitorsService.getMonitors()
  }

And in swagger it shows something like this: enter image description here

However, is there any way to setup NestJs to have the same things with inputDTO and not to write in each dto @ApiProperty?

As in example below:

ExampleDto.ts

export class GetListUsersDto {
  @ApiProperty()
  @IsString()
  name: string
  @ApiProperty()
  @IsString()
  email: string
  @ApiProperty()
  @IsString()
  publicApiKey: string
  @ApiProperty()
  @IsBoolean()
  isAdmin: boolean
  @ApiProperty()
  @IsBoolean()
  isDesigner: boolean
  @ApiProperty()
  @IsBoolean()
  isEditor: boolean
  @ApiProperty()
  @IsBoolean()
  isEnabled: boolean
  @ApiProperty()
  @IsString()
  boughtProduct: string
}

And only after @ApiProperty it will show the structure as shown above for input in swagger.

Daniil Sinelnik
  • 244
  • 1
  • 5
  • 13

5 Answers5

6

There is no way around decorating your DTO properties. However, if your DTOs have a lot in common, you might be looking for mapped types. Documentation can be found here.

These essentially allow you to transform existing types to keep your DTOs DRY.

Antoine Viscardi
  • 722
  • 1
  • 7
  • 15
  • I'd like to note that, as per @Deivy Gutierrez's answer, for those using the Nest CLI, there is a plugin that will decorate your DTOs for you. For those not using Nest CLI, you'll have to decorate your properties or come up with a custom solution. – Antoine Viscardi Apr 14 '23 at 02:56
5

If you are using cli-plugin you don't need to add @ApiProperty. Check docs openapi/cli-plugin

try this

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  @IsOptional()
  isEnabled?: boolean = true;
}
  • Using this plugin is the correct answer. https://docs.nestjs.com/openapi/cli-plugin#using-the-cli-plugin – ttemple Feb 17 '23 at 16:01
3

Using the plugin resolved this issue for me, see https://docs.nestjs.com/openapi/cli-plugin#using-the-cli-plugin.

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

{
  "collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }
}

Then this will automatically apply the @ApiProperty() without having to add it

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  @IsOptional()
  isEnabled?: boolean = true;
}
ttemple
  • 1,825
  • 2
  • 17
  • 12
0

Note that using

Using the plugin resolved this issue for me, see https://docs.nestjs.com/openapi/cli-plugin#using-the-cli-plugin.

your DTO file should be named <my_dto_name>.dto.ts

jmchey
  • 33
  • 6
-1

Simply adding this in your dto file will auto apply for all properties

import { ApiProperty } from '@nestjs/swagger';

Magic will happen to wherever you need it. Hope this helps.

princecharmx
  • 181
  • 1
  • 6