@Query와 TypeORM으로 GET method API Pagination 하기

GET 메소드를 활용하는 Restful 방식의 API를 구성할 때, 해당 테이블 내의 모든 정보를 가져오는 findAll( ) 방식의 API는 테이블에 데이터가 많아질 경우, 성능 이슈와 서버 메모리 사용량 증가로 인한 비용 이슈가 발생할 수 있다.

Page 단위로 데이터를 분할하여 전달하는 방식으로 TypeORM의 createQueryBuilder( )를 활용하여 구성하였다.

// user.service.ts

async findCollectors(page, limit) {
    return await this.repository
      .createQueryBuilder('user') // user 테이블로 전달할 쿼리문임을 정의합니다.
      .where('user.role = COLLECTOR') // user 테이블을 role 칼럼의 값이 COLLECTOR 인 것만
      .offset(page) // page 간격을 나눕니다.
      .limit(limit) // 한번에 불러오는 값의 개수에 입력받은 만큼으로 제한을 겁니다.
      .getMany(); // 여러 개의 결과를 가져온다.
  }

위의 코드는 유저 중 콜렉터의 권한을 가진 유저들의 정보를 데이터베이스의 유저 테이블에서 가져오는 기능을 하는 함수이다.

// user.controller.ts

@Get('/collectors')
  async getCollector(
    @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
    @Query('limit', new DefaultValuePipe(16), ParseIntPipe) limit: number,
  ) {
    return await this.service.findCollectors(page, limit);
  }

user.service.ts에서 정의한 findCollectors( )에 page, limit 두 가지 변수의 값을 가지고 호출합니다.

위의 코드에서 DefaultValuePipe( )는 쿼리로 받아오는 page와 limit의 default 값을 각각 1 과 16으로 정의합니다.

그 뒤의 ParseIntPipe는 @Query( )를 통해 받아온 page의 값이 number형이 아닌 String형이기 때문에 page를 String에서 number로 변환합니다.