Tips on skipping the need to repeatedly use `@ApiProperty()` for every dto in NestJs-swagger

I'm currently exploring ways to streamline the process of specifying @ApiProperty() for each DTO.

I've heard about a method involving the creation of a nest-cli.json file, where if you define Promise<DTO> in your controller within nest-swagger, it will automatically generate the output DTO from the route.

The configuration typically appears 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> { // <-- This is my outputDto
    return this.monitorsService.getMonitors()
  }

In Swagger, the result would resemble something similar to this: https://i.sstatic.net/LEUez.png

However, I am wondering if there is a way to configure NestJs to achieve the same effect with inputDTO without the need to manually add @ApiProperty to each DTO?

For instance:

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
}

With this setup, only tagging with @ApiProperty would display the structured input on Swagger, similar to the example provided above.

Answer №1

When it comes to decorating your DTO properties, there's really no way around it. However, if you find that your DTOs share a lot of similarities, you may want to explore the concept of mapped types. You can check out the documentation on mapped types here.

These tools essentially allow you to streamline your DTOs by transforming existing types and keeping them DRY.

Answer №2

For those utilizing the cli-plugin, there is no need to include @ApiProperty. Refer to the documentation at openapi/cli-plugin

Give this a shot:

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  @IsOptional()
  isEnabled?: boolean = true;
}

Answer №3

I found a solution to my issue by utilizing a helpful plugin, which you can learn more about at https://docs.nestjs.com/openapi/cli-plugin#using-the-cli-plugin.

If you want to activate the plugin, simply access the file nest-cli.json (if you are using Nest CLI) and insert the specified configurations for plugins:

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

This will automatically apply @ApiProperty() without requiring manual addition.

export class CreateUserDto {
  email: string;
  password: string;
  roles: RoleEnum[] = [];
  @IsOptional()
  isEnabled?: boolean = true;
}

Answer №5

If you include this code snippet in your data transfer object (DTO) file, it will automatically be applied to all properties.

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

This magical line of code will work wonders wherever you may need it. I hope this tip proves helpful to you.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combine two arrays into one

When attempting to combine two arrays, the result looks like the image linked below: https://i.sstatic.net/3FWMZ.png I want the merged array to resemble the following example: {0: {…}, storedArr: Array(2)} 0: address: "ifanio de los Santos Ave, Ma ...

Guide to displaying a partial in the controller following an ajax request

After initiating an AJAX request to a method in my controller, I am attempting to display a partial. Below is the AJAX call I am currently using: $('.savings_link').click(function(event){ $.ajax({ type: 'GET', url: '/topi ...

What is the best way to locate all mesh faces that are being lit up by a SpotLight

I am working with a THREE.Mesh that consists of a THREE.BufferGeometry containing "position" and "normal" THREE.BufferAttributes. This mesh is being lit by a THREE.SpotLight (which is a cone-shaped light source). Is there a method to ...

Implement dynamic configuration injection by allowing users to specify the name of a configuration file during runtime, instead of having it fixed in the code

In my development using webpack, I am exploring ways to make my application configurations more dynamic. Presently, the project is a create-react-app that has been ejected. For instance, when creating a local build in my package.json file, I include the f ...

Utilizing interpolation for a CSS class defined in an external file within Angular 2

Is it feasible to send a variable to a CSS class in an external CSS file within Angular 2, such as: import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', sty ...

Trigger a Tabulator event when a checkbox is selected in Vue 3

Currently, I am utilizing Vue3 along with Tabulator (5.2.7) to create a data table using the Composition API. In the following code snippets, I have excluded irrelevant parts of the code. //DataTable.vue <script setup> import { TabulatorFull as Tabu ...

Navigating a Multi-Page Website with Sleek Scrolling

I've been searching for a solution everywhere but haven't had any luck. I'm trying to implement a smooth scroll effect that works seamlessly across multiple pages. For instance, the smooth scroll effect is present on the homepage with naviga ...

AJAX (Vanilla JavaScript): Sending Image through HTTP Request

I am a beginner with ajax and prefer not to use frameworks. I attempted to use PHP to determine if a file is set and display either true or false, but it didn't work as expected. I'm unsure of where I went wrong. Below is my HTML and JS code: & ...

What is the best way to delegate the anonymous function logic contained within the subscribe() method?

Imagine you have a code block similar to this: constructor(private _http: HttpClient) { this.fetchUsers(5); } employees: any[] = []; fetchUsers(count: number) { this._http.get(`https://jsonplaceholder.typicode.com/users`).subscribe( ...

Trapped in a Continuous Observing Loop with MdSnackBar in Angular Material within Angular 2

Whenever my login attempt fails, I want to display a snackbar with the message 'error connecting'. After dismissing the snackbar, I would like the login to be retried after 10 seconds. However, I'm facing an issue where my observable is runn ...

I seem to be missing some properties in the request body schema. Why am I receiving an incomplete model for

Seeking assistance in grasping the working of models in loopback4. Here's a model I defined: @model() export class ProductViewConfig extends BaseConfig { @property({ type: 'string', id: true, generated: true, }) _id?: strin ...

JavaScript: A guide to finding CSS properties within a string

Checking for CSS Properties in Over 1,000 Sentences Is there a way in Javascript to check sentences against a built-in CSS index? Currently… If I need to search for CSS properties in the sentences below, I have to create an array containing all the CS ...

Troubleshooting Error 405 in AJAX, Javascript, Node.js (including Body-Parser and CORS), and XMLHttpRequest

I have been working on creating a JSON file from buttons. While I am able to retrieve data from the JSON files that I created, I am facing issues with posting to them using XMLHttpRequest and Ajax. Interestingly, I can add to a JSON file using routes just ...

Struggling with Nuxt 3 Firebase and VueFire: unable to get useCurrentUser to work

Currently, I am attempting to implement VueFire's useCurrentUser() function within a Nuxt 3 application that does not utilize Server Side Rendering. I have properly configured vuefire in my nuxt.config.ts file as outlined in the documentation. export ...

What is the best way to create an AngularJS page with a direct link that will dynamically affect the content on the

I have a webpage similar to Google search where the backend generates a list of items. The page features an HTML form with multiple fields for users to modify values, resulting in a refreshed list of items from the backend. Currently, users can create a ...

Tips for generating a hyperlink in a Typescript file using Angular version 16 and above

I am encountering an issue with my consts.ts file in the project. Specifically, I have defined a constant LINK1 as <a href='https://sample.com/'>LINK 1</a>; However, this setup is not working as expected. What I actually want is to d ...

What is the best way to retrieve class properties within an input change listener in Angular?

I am new to Angular and have a question regarding scopes. While I couldn't find an exact match for my question in previous queries, I will try to clarify it with the code snippet below: @Component({ selector: 'item-selector&apos ...

What is the best way to generate the message dynamically?

I have implemented the react-intl package for translation purposes in my project. Users have the option to choose between Spanish and English languages, with Spanish being the default language. When a user switches to English, all text should be dynamicall ...

Should we bundle everything into one script with webpack, considering Npm and Dev dependency or just dependencies?

Imagine a scenario where we use webpack to bundle all our code into a single JS file, which automatically imports dependencies. In this case, is it necessary to include any dependencies in the package.json, or can they all be listed as --save-dev? Let&apo ...

Retrieve data from an HTML form and utilize it to search a JSON array for a specific value

If I have a Json File structured like this: {"403": [ { "403-01-01": "219,00" }, { "403-01-02": "180,00" } ], "404": [ { "404-01-01": "26,00" }, {"403-01-02": " ...