Better Swagger / OpenAPI types
caioquirino opened this issue · comments
Hello, good morning! Thanks for creating and maintaining such nice tool to ease our lifes with pagination! I am using it together with Swagger yaml generation and swagger-codegen in a Monorepo, so I can get type safety in the entire Full-Stack project.
When I use @nestjs/swagger with nestjs-typeorm-paginate, since it uses generics for the Pagination object, I had to manually annotate the Schema so it gets described properly in the swagger file.
I am wondering if we can either annotate the types in this project so it gets a more out-of-the-box swagger generation experience, or if the utility decorator can be part of it as well as some instructions in how to implement it properly :)
In any ways, here is the decorator that solved my problem:
import { Pagination } from 'nestjs-typeorm-paginate'
import { Type, applyDecorators } from "@nestjs/common"
import { ApiExtraModels, ApiOkResponse, getSchemaPath } from '@nestjs/swagger'
export const ApiOkResponsePaginated = <DataDto extends Type<unknown>>(dataDto: DataDto) =>
applyDecorators(
ApiExtraModels(Pagination, dataDto),
ApiOkResponse({
schema: {
allOf: [
{ $ref: getSchemaPath(Pagination) },
{
properties: {
items: {
type: 'array',
items: { $ref: getSchemaPath(dataDto) },
},
meta: {
type: 'object',
properties: {
'itemCount': {
type: 'number'
},
'totalItems': {
type: 'number'
},
'itemsPerPage': {
type: 'number'
},
'totalPages': {
type: 'number'
},
'currentPage': {
type: 'number'
}
},
required: ['itemCount', 'totalItems', 'itemsPerPage', 'totalPages', 'currentPage']
},
links: {
type: 'object',
properties: {
'first': {
type: 'string'
},
'previous': {
type: 'string'
},
'next': {
type: 'string'
},
'last': {
type: 'string'
}
}
}
},
required: ['items', 'meta']
},
],
},
})
)
And the way I have used is:
@ApiQuery({ name: 'page', type: "number" })
@ApiQuery({ name: 'limit', type: "number" })
@ApiOkResponsePaginated(Cat)
@Get()
findAll(
@Query('page', new DefaultValuePipe(1), ParseIntPipe) page = 1,
@Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit = 10,
): Promise<Pagination<Cat>> {
limit = limit > 10 ? 10 : limit
return this.catsService.findAll({ page, limit })
}
Cheers!