#How to prevent Swagger from spreading DTO property.

11 messages · Page 1 of 1 (latest)

languid crater
#

Hello, I'm creating a query: @Query() query: AnalyticsRequestDTO<G> for my GET endpoint that consist of a DTO that looks like this:

export class AnalyticsRequestDTO<
        G extends GroupableKeys,
        P extends PopulateableKeys<G> | undefined = undefined
    >
    implements AggregateRunLogAnalyticsOptions<G, P>
{
    @IsObject()
    @IsOptional()
    @ApiProperty({
        description: 'Filters to apply to run logs before aggregating',
        required: false,
    })
    filter: AnalyticsFilterDTO = {}

    @IsArray()
    @ApiProperty({
        description: 'The fields to group by',
        required: false,
    })
    groupBy: G[]

    @IsArray()
    @IsOptional()
    @ApiProperty({
        description: [
            'Populate certain fields by joining with other collections.',
            '',
            'Values in this list must be a subset of `groupBy`, and can only',
            'apply to id fields. Instead of containing',
            'an ObjectId, populated fields will contain the document the id',
            'refers to.',
        ].join('\n'),
        type: [String],
        required: false,
    })
    populate?: P[]
}

The problem here is that the AnalyticsFilterDTO is getting spread, like you can see in the attached image. I want to know how to prevent this from happening, as the normal behavior is to send the query wrapped in the filter object (i.e. { filter: { ruleId: '...', appId: '..', ... }).

ancient spear
#

You're extending the AnalyticsFilterDto, so of course the AnalyticsRequestDto class has all of those properties

languid crater
#

Sorry, it's not extending it, and still spreading it. It was me playing around with it, just edited it.

ancient spear
#
export class AnalyticsRequestDTO<
        G extends GroupableKeys,
        P extends PopulateableKeys<G> | undefined = undefined
    >
    extends AnalyticsFilterDTO
    implements AggregateRunLogAnalyticsOptions<G, P>
{
...
}

Looks like it's extending it to me.

languid crater
#

You're right, I'm sorry, just edited the code snippet, but I'm still getting the same behavior without it.

ancient spear
#

Got a reproduction then? Something minimal that shows this samer behavior

languid crater
#

@ancient spear Thanks for helping me. Here's the code reproducing it:

class FilterDTO {
    @IsOptional()
    @IsString()
    @ApiProperty({
        type: String,
        required: false,
    })
    foo?: string

    @IsOptional()
    @IsString()
    @ApiProperty({
        type: String,
        required: false,
    })
    bar?: string
}
class QueryDTO {
    @IsObject()
    @IsOptional()
    @ValidateNested()
    @ApiProperty({
        required: false,
    })
    filter?: FilterDTO
}

@Controller('foo')
@ApiTags('foo')
export class FooController {
    public constructor() {}

    @Get('')
    @ApiOperation({})
    @ApiResponse({
        type: String,
        status: HttpStatus.OK,
    })
    @ApiQuery({ type: QueryDTO, required: false })
    @HttpCode(HttpStatus.OK)
    public async getRun(@Query() query?: QueryDTO) {
        return 'bar' + JSON.stringify(query)
    }
}

@Module({
    imports: [],
    providers: [],
    controllers: [FooController],
})
export class FooModule {}

And swagger adds the filter, but also add's the properties outside the filter as you can see in the image.

ancient spear
#

Can you create this in a git repo?

languid crater
languid crater
#

@ancient spear Hello, were you able to look at the problem?

ornate ember
#

Why do you want to put an object in query?