How to avoid to write `@ApiProperty()` in each dto for NestJs-swagger
Asked Answered
B

5

10

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.

Balliett answered 22/4, 2022 at 9:47 Comment(0)
B
7

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.

Bakery answered 22/4, 2022 at 13:1 Comment(1)
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.Bakery
P
6

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;
}
Paralyze answered 23/9, 2022 at 17:30 Comment(1)
Using this plugin is the correct answer. docs.nestjs.com/openapi/cli-plugin#using-the-cli-pluginJerrodjerrol
J
6

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;
}
Jerrodjerrol answered 21/2, 2023 at 17:12 Comment(0)
D
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

Drunk answered 23/3, 2023 at 9:57 Comment(2)
Can you please add explanation why?Balliett
Because the documentation of the CLI Plugin in the Options section says that it's the default convention @daniilsinelnikFlamethrower
D
-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.

Dispense answered 17/8, 2023 at 7:50 Comment(1)
above works for meDispense

© 2022 - 2024 — McMap. All rights reserved.