본문 바로가기
개발/NestJS

[NestJS] TypeORM Pagination: 설치, 사용법, 직접 구현과의 비교 with nestjs-paginate

by coking 2024. 11. 5.

NestJS 프로젝트에서 데이터베이스 쿼리 결과를 페이징 처리할 때 TypeORM을 많이 사용하는데, 페이징을 쉽게 구현할 수 있도록 돕는 라이브러리 중 하나가 nestjs-typeorm-paginate입니다. 이 글에서는 nestjs-typeorm-paginate의 설치 방법과 사용법, 그리고 직접 페이징 로직을 구현하는 것과의 차별점을 살펴보겠습니다.

1. nestjs-typeorm-paginate 설치

nestjs-typeorm-paginate를 설치하려면 다음 명령어를 실행하세요:

npm install nestjs-typeorm-paginate

또는 yarn을 사용하는 경우:

yarn add nestjs-typeorm-paginate

2. 사용법

nestjs-typeorm-paginate를 사용하려면, NestJS의 서비스(service)에서 데이터를 페이징 처리하는 로직을 다음과 같이 작성할 수 있습니다. 간단한 예제를 통해 살펴보겠습니다:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { paginate, Pagination, IPaginationOptions } from 'nestjs-typeorm-paginate';
import { User } from './entities/user.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) {}

  async getUsers(options: IPaginationOptions): Promise<Pagination<User>> {
    const queryBuilder = this.userRepository.createQueryBuilder('user');
    queryBuilder.orderBy('user.id', 'ASC');

    return paginate<User>(queryBuilder, options);

    /**
      const paginatedData = await paginateRaw<queryBuilder>(findSubscriptionQuery, {
        page: query.page || 1,
        limit: query.limit || 10,
      });
    */ options 값을 이렇게 넣어도 되고 raw쿼리 사용도 가능
  }
}

결과 값 예시

{
    "items": [
        {
         "testValue":"tt"
        }
    ],
    "meta": {
        "totalItems": 10,
        "itemCount": 3,
        "itemsPerPage": 3,
        "totalPages": 4,
        "currentPage": 1
    }
}

위 예제에서는 paginate 함수와 createQueryBuilder를 이용해 데이터베이스에서 User 데이터를 페이징 처리하고 있습니다. paginate 함수는 queryBuilderIPaginationOptions를 입력받아 간단히 페이지네이션 결과를 반환합니다.

Controller에서 사용하기

다음으로, 이 서비스 메서드를 컨트롤러에서 호출하는 예시입니다:

import { Controller, Get, Query } from '@nestjs/common';
import { UserService } from './user.service';
import { Pagination } from 'nestjs-typeorm-paginate';
import { User } from './entities/user.entity';

@Controller('users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  @Get()
  async getUsers(
    @Query('page') page: number = 1,
    @Query('limit') limit: number = 10,
  ): Promise<Pagination<User>> {
    limit = limit > 100 ? 100 : limit; // 최대 limit을 100으로 제한
    return this.userService.getUsers({ page, limit });
  }
}

위 코드에서는 사용자가 pagelimit 파라미터를 통해 원하는 페이지와 데이터 수를 지정할 수 있습니다.

3. 직접 페이징 구현과의 차이점

직접 페이징 로직 구현

페이징을 직접 구현하는 경우, 다음과 같은 로직을 작성해야 합니다:

async getUsers(page: number, limit: number): Promise<{ data: User[]; total: number }> {
  const [data, total] = await this.userRepository.findAndCount({
    skip: (page - 1) * limit,
    take: limit,
    order: { id: 'ASC' },
  });
  return { data, total };
}

위 방법은 비교적 간단해 보일 수 있지만, 추가적인 페이지 정보(예: 총 페이지 수, 다음/이전 페이지 여부 등)를 계산하는 코드를 작성해야 하며, 중복된 코드가 발생할 수 있습니다. 또한, 쿼리 빌더를 사용하는 복잡한 쿼리의 경우에는 직접 페이징 처리가 더욱 어려워질 수 있습니다.

nestjs-typeorm-paginate 사용의 장점

  • 간편한 사용: 페이징 관련 로직을 직접 작성할 필요 없이 paginate 함수를 사용하여 쉽게 처리할 수 있습니다.
  • 일관성: 여러 곳에서 페이징 처리를 구현할 때 일관된 방식을 유지할 수 있습니다.
  • 추가 기능: nestjs-typeorm-paginate는 총 페이지 수, 현재 페이지, 다음 페이지 존재 여부 등 다양한 메타데이터를 자동으로 제공하므로, 클라이언트에 더 많은 정보를 쉽게 전달할 수 있습니다.

4. 마치며

nestjs-typeorm-paginate는 NestJS와 TypeORM을 사용할 때 페이징 처리를 매우 쉽게 구현할 수 있도록 돕는 유용한 라이브러리입니다. 직접 구현하는 것에 비해 코드의 복잡성을 줄이고, 일관성을 높일 수 있다는 점에서 많은 장점을 제공합니다. 특히, 복잡한 쿼리의 페이징을 간단히 처리하고 싶다면 이 라이브러리를 적극 추천합니다.

}

댓글