Play with the following (eg, you can add a constructor function to map properties, or some class-validator fn, like @IsInt, @Min, etc.):
import { Type, applyDecorators } from '@nestjs/common';
import { ApiExtraModels, ApiOkResponse, ApiProperty, getSchemaPath } from '@nestjs/swagger';
import { PaginationResponseDto } from '@shared';
export class PaginationModel<T> implements PaginationResponseDto<T> {
@ApiProperty({ isArray: true })
public readonly data: T[];
@ApiProperty({ example: 1 })
public readonly total: number;
@ApiProperty({ example: 1 })
public readonly page: number;
@ApiProperty({ example: 1 })
public readonly pages: number;
}
And a decorator for query:
import { ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
export class PaginationQuery {
@ApiPropertyOptional({
default: 1,
})
@Type(() => Number)
public readonly page?: number;
@ApiPropertyOptional({
default: 20,
})
@Type(() => Number)
public readonly take?: number;
}
A controller decorators for response:
export const ApiPaginatedResponse = <TModel extends Type<any>>(model: TModel) => {
return applyDecorators(
ApiExtraModels(PaginationModel),
ApiQuery({ type: () => PaginationQuery }),
ApiOkResponse({
description: 'Successfully received model list',
schema: {
allOf: [
{ $ref: getSchemaPath(PaginationModel) },
{
properties: {
data: {
type: 'array',
items: { $ref: getSchemaPath(model) },
},
},
},
],
},
})
);
};
Example usage:
@Get()
@ApiOperation({ summary: 'find paginated users' })
@ApiPaginatedResponse(UserModel)
// public async findUsers(...otherLogic