From c43b18daf6501b61dc8beb489726f612e380ed6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B0=AC=EA=B8=B0?= Date: Fri, 5 Apr 2024 18:46:39 +0900 Subject: [PATCH 1/2] refac: Project API Pagination Add --- docs/projects/projects.swagger.ts | 20 ++++++++++++++++++- .../controllers/projects.controller.ts | 9 ++++++--- src/projects/dtos/get-projects-request.dto.ts | 3 ++- src/projects/services/project.service.ts | 19 ++++++++++++++++++ src/utils/helper.ts | 6 ++++++ 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/docs/projects/projects.swagger.ts b/docs/projects/projects.swagger.ts index e3c969b..b72641e 100644 --- a/docs/projects/projects.swagger.ts +++ b/docs/projects/projects.swagger.ts @@ -1,9 +1,11 @@ import { applyDecorators } from '@nestjs/common'; import { + ApiExtraModels, ApiOkResponse, ApiOperation, ApiParam, ApiQuery, + getSchemaPath, } from '@nestjs/swagger'; import { ProjectType } from 'src/projects/dtos/category'; import { ProjectDetailResponseDto } from 'src/projects/dtos/project-detail-response.dto'; @@ -11,12 +13,14 @@ import { ProjectsResponseDto, ServiceType, } from '../../src/projects/dtos/projects-response.dto'; +import { PaginateResponseDto } from '../../src/utils/paginate-response.dto'; export function GetProjectsDocs() { return applyDecorators( ApiOperation({ summary: '프로젝트 정보 전부 가져오기', }), + ApiExtraModels(PaginateResponseDto, ProjectsResponseDto), ApiQuery({ name: 'filter', type: String, @@ -31,7 +35,21 @@ export function GetProjectsDocs() { description: '웹/앱 필터링', enum: ServiceType, }), - ApiOkResponse({ type: [ProjectsResponseDto] }), + ApiOkResponse({ + schema: { + allOf: [ + { $ref: getSchemaPath(PaginateResponseDto) }, + { + properties: { + data: { + type: 'array', + items: { $ref: getSchemaPath(ProjectsResponseDto) }, + }, + }, + }, + ], + }, + }), ); } diff --git a/src/projects/controllers/projects.controller.ts b/src/projects/controllers/projects.controller.ts index a4a8866..01c4dbb 100644 --- a/src/projects/controllers/projects.controller.ts +++ b/src/projects/controllers/projects.controller.ts @@ -10,6 +10,7 @@ import { compareProjects } from 'src/utils/compare'; import { ProjectsResponseDto } from '../dtos/projects-response.dto'; import { GetSopticleListRequestDto } from '../../sopticle/dtos/get-sopticle-list-request.dto'; import { GetProjectsRequestDto } from '../dtos/get-projects-request.dto'; +import { PaginateResponseDto } from '../../utils/paginate-response.dto'; @ApiTags('Project') @Controller('projects') @@ -20,9 +21,11 @@ export class ProjectsController { @GetProjectsDocs() async getProjects( @Query() getProjectsRequestDto: GetProjectsRequestDto, - ): Promise { - const projects = await this.projectsService.findAll(getProjectsRequestDto); - projects.sort(compareProjects); + ): Promise> { + const projects = await this.projectsService.paginateProjects( + getProjectsRequestDto, + ); + projects.data.sort(compareProjects); return projects; } diff --git a/src/projects/dtos/get-projects-request.dto.ts b/src/projects/dtos/get-projects-request.dto.ts index ce8f3fd..e26ef64 100644 --- a/src/projects/dtos/get-projects-request.dto.ts +++ b/src/projects/dtos/get-projects-request.dto.ts @@ -1,8 +1,9 @@ import { IsEnum, IsOptional } from 'class-validator'; import { ProjectType } from './category'; import { ServiceType } from './projects-response.dto'; +import { PageRequest } from '../../utils/paginate-request.dto'; -export class GetProjectsRequestDto { +export class GetProjectsRequestDto extends PageRequest { @IsEnum(ProjectType) @IsOptional() readonly filter: ProjectType | null; diff --git a/src/projects/services/project.service.ts b/src/projects/services/project.service.ts index cbc2fff..1e34391 100644 --- a/src/projects/services/project.service.ts +++ b/src/projects/services/project.service.ts @@ -3,6 +3,8 @@ import { ProjectDetailResponseDto } from 'src/projects/dtos/project-detail-respo import { ProjectsResponseDto } from '../dtos/projects-response.dto'; import { PlaygroundService } from 'src/internal/playground/playground.service'; import { GetProjectsRequestDto } from '../dtos/get-projects-request.dto'; +import { PaginateResponseDto } from '../../utils/paginate-response.dto'; +import { paginateArray } from '../../utils/helper'; @Injectable() export class ProjectService { @@ -21,4 +23,21 @@ export class ProjectService { const projects = await this.findAll(); return projects.filter((project) => project.generation === generation); } + + async paginateProjects( + dto: GetProjectsRequestDto, + ): Promise> { + const allProjects = await this.findAll(dto); + const paginatedProject = paginateArray( + allProjects, + dto.pageNo, + dto.limit, + ); + return new PaginateResponseDto( + paginatedProject, + allProjects.length, + dto.getLimit(), + dto.pageNo, + ); + } } diff --git a/src/utils/helper.ts b/src/utils/helper.ts index 32f9ac9..0af48a0 100644 --- a/src/utils/helper.ts +++ b/src/utils/helper.ts @@ -11,3 +11,9 @@ export function dropDuplication(array: T[], property: O) { } return uniqueArray; } + +export function paginateArray(items: T[], page: number, limit: number): T[] { + const offset = (page - 1) * limit; + + return items.slice(offset, offset + limit); +} From 1f0b979a1eb83b33a42091a24fed9791d9487d55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=B0=AC=EA=B8=B0?= Date: Wed, 24 Apr 2024 11:59:46 +0900 Subject: [PATCH 2/2] fix: set puppeteer timeout to 0 to prevent from server going down --- src/scraper/scraper.service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scraper/scraper.service.ts b/src/scraper/scraper.service.ts index 379cf9e..970cbc9 100644 --- a/src/scraper/scraper.service.ts +++ b/src/scraper/scraper.service.ts @@ -110,6 +110,7 @@ export class ScraperService { '--disable-setuid-sandbox', '--disable-dev-shm-usage', ], + timeout: 0, }; if (!this.configService.get('LOCAL')) {