Search code examples
nestjsnestjs-swagger

Is there a way to declare a default value when using @ApiQuery with nestJS and swagger?


EDIT: found a solution thanks to the comment suggesting to use a DTO. Answer detailed at the bottom.

The NestJS website has documentation to [declare default values][1] when using @ApiBody(), is there a way to do so with @ApiQuery()? (i.e. show in the documentation that the queries have default values)

for example, if I have pagination queries and want the default to be page 1 with 5 entries per page:

  @Get()
  @ApiQuery({name: 'page', default: 1, type: Number})
  @ApiQuery({name: 'limit', default: 5, type: Number})
  async getDocuments(
    @Query('page') page: Number = 1, 
    @Query('limit') limit: Number = 5
  ){
    return this.documentsService.getDocuments(page, limit);
  }

Solution

  • Using DTO as suggested in the comments:

    //dto.ts
    export class PageDTO {
      @ApiProperty({default: 1, required: false})
      page: Number
    }
    export class LimitDTO {
      @ApiProperty({default: 5, required: false})
      limit: Number
    }
    //documents.controller.ts
    ...
      @Get()
      @ApiQuery({name: 'page', default: 1, type: PageDTO})
      @ApiQuery({name: 'limit', default: 5, type: LimitDTO})
      async getDocuments(
        @Query('page') page = 1, 
        @Query('limit') limit = 5
      ){
        return this.documentsService.getDocuments(page, limit);
      }
    

    The result: Generated documentation page *made a typo, default here says 0 but it should be 1

    Furthermore, a single DTO can be used for multiple query parameters. This is especially useful if the same params are being used by multiple functions:

    //dto.ts
    export class PaginationDTO {
      @ApiProperty({default: 1, required: false})
      page: Number
      @ApiProperty({default: 5, required: false})
      limit: Number
    }
    
    //documents.controller.ts
    ...
      @Get()
      @ApiQuery({type: PaginationDTO})
      async getDocuments(
        @Query('page') page = 1, 
        @Query('limit') limit = 5 
      ){
        return this.documentsService.getDocuments(page, limit);
      }
    

    Also note the omission of type declarations on my working examples --this is because if the type is declared, swagger produces duplicate params