1. DTO์ Page ํ๋กํผํฐ ์ถ๊ฐ
paginatePosts()๋ฅผ 2๊ฐ์ง ํจ์๋ก ๋๋ ๊ฒ์ด๋ค.
- pagePaginatePosts
- cursorPaginatePosts
posts.service.ts
1// posts.service.ts ์๋ต2/***3* 1) ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ pagination๋ง ๊ตฌํํ๋ค4*/5async paginatePosts(dto: PaginatePostDto) {6if (dto.page) {7return this.pagePaginatePosts(dto)8} else {9return this.cursorPaginatePosts(dto)10}11}1213/*** ํ์ด์ง ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์ 14* data: Data[],15* total: number16*/17async pagePaginatePosts(dto: PaginatePostDto) {}1819/*** ์ปค์ ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์ 20*21*/22async cursorPaginatePosts(dto: PaginatePostDto) {23const where: FindOptionsWhere<PostsModel> = {}2425if (dto.where__id_less_than) {26where.id = LessThan(dto.where__id_less_than)27} else if (dto.where__id_more_than) {28where.id = MoreThan(dto.where__id_more_than)29}3031const posts = await this.postsRepository.find({32where,33order: {34createdAt: dto.order__createAt,35},36take: dto.take,37})3839/****40* ํด๋น๋๋ ํฌ์คํธ๊ฐ 0๊ฐ ์ด์์ด๋ฉด, ๋ง์ง๋ง ํฌ์คํธ๋ฅผ ๊ฐ์ ธ์ค๊ณ41* ์๋๋ฉด null์ ๋ฐํํ๋ค.42*/43const lastItem = posts.length > 0 && posts.length === dto.take ? posts[posts.length - 1] : null44const nexttUrl = lastItem && new URL(`${PROTOCOL}://${HOST}/posts`)4546/**** dto์ ํค๊ฐ๋ค์ ๋ฃจํํ๋ฉด์47* ํค๊ฐ์ ํด๋น๋๋ ๋ฒจ๋ฅ๊ฐ ์กด์ฌํ๋ฉด, parame์ ๊ทธ๋๋ก ๋ถ์ฌ๋ฃ๋๋ค.48* ๋จ, where__id_more_than ๊ฐ๋ง lastItem์ ๋ง์ง๋ง ๊ฐ์ผ๋ก ๋ฃ์ด์ค๋ค.49*/50if (nexttUrl) {51for (const key of Object.keys(dto)) {52if (dto[key]) {53if (key !== 'where__id_more_than' && key !== 'where__id_less_than') {54nexttUrl.searchParams.append(key, dto[key])55}56}57}58let key = null59if (dto.order__createAt === 'ASC') {60key = 'where__id_more_than'61} else {62key = 'where__id_less_than'63}64nexttUrl.searchParams.append(key, lastItem.id.toString())65}6667/*** Response68* data : Data[],69* cursor : {70* after: ๋ง์ง๋ง Data์ ID71* }72* count: ์๋ตํ ๋ฐ์ดํฐ์ ๊ฐ์73* next: ๋ค์ ์์ฒญ์ ํ ๋ ์ฌ์ฉํ URL74*/75return {76data: posts,77cursor: {78after: lastItem?.id ?? null,79},80count: posts.length,81nest: nexttUrl?.toString() ?? null,82}83}
๊ทธ๋ฆฌ๊ณ paginate-post.dto์ page ํ๋กํผํฐ๋ฅผ ์ถ๊ฐํด์ผ ํ๋ค.
paginate-post.dto.ts
1// ์๋ต2export class PaginatePostDto {3@IsNumber()4@IsOptional()5page?: number67// ์๋ต8}
2. Post ์๋ต ์์ฑ
posts.service.ts
1// posts.service.ts ์๋ต2/*** ํ์ด์ง ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์ 3* data: Data[],4* total: number5*/6async pagePaginatePosts(dto: PaginatePostDto) {7const posts = await this.postsRepository.find({8skip: dto.take * (dto.page - 1), // 1ํ์ด์ง๋ถํฐ ์์ํ๋๋ก9take: dto.take,10order: {11createdAt: dto.order__createAt,12},13})1415return {16data: posts,17}18}
3. ์๋ต์ total ํ๋กํผํฐ ์ถ๊ฐ
posts.service.ts
1// posts.service.ts ์๋ต2/*** ํ์ด์ง ๊ธฐ๋ฐ ํ์ด์ง๋ค์ด์ 3* data: Data[],4* total: number5*/6async pagePaginatePosts(dto: PaginatePostDto) {7const [posts, count] = await this.postsRepository.findAndCount({8skip: dto.take * (dto.page - 1), // 1ํ์ด์ง๋ถํฐ ์์ํ๋๋ก9take: dto.take,10order: {11createdAt: dto.order__createAt,12},13})1415return {16data: posts,17total: count,18}19}