관리 메뉴

거니의 velog

(19) mongoose를 이용한 MongoDB 연동 실습 8 본문

React/React_백엔드 프로그래밍

(19) mongoose를 이용한 MongoDB 연동 실습 8

Unlimited00 2024. 2. 21. 12:19

10. 페이지네이션 구현

* 블로그에서 포스트 목록을 볼 때 한 페이지에 보이는 포스트의 갯수는 10~20개 정도가 적당하다. 지금 만든 list API는 현재 작성된 모든 포스트를 불러오는데, 포스트 갯수가 몇 백 개라면 로딩 속도가 느려질 것이다. 또 포스트 목록을 볼 때 포스트 전체 내용을 보여 줄 필요는 없고, 처음 200자(글자) 정도만 보여 주면 적당하다. 불필요하게 모든 내용을 보여 주면 역시 로딩 속도가 지연되고, 트래픽이 낭비될 것이다.

* 따라서 list API에 페이지네이션(pagination) 기능을 한 번 구현해 보겠다.


(1) 가짜 데이터 생성하기

* 페이지네이션 기능을 구현하려면 우선 데이터가 충분히 있어야 한다. 수작업을 직접 등록을 해도 좋지만, 좀 더 편하게 데이터를 채우기 위해 가짜 데이터를 생성하는 스크립트를 작성해 보자.

* src 디렉터리에 createFakeData.js 라는 파일을 만들자.

import Post from './models/post';

export default function createFakeData() {
  // 0, 1, ... 39 로 이루어진 배열 생성 후 포스트 데이터로 변환
  const posts = [...Array(40).keys()].map((i) => ({
    title: `포스트 #${i}`,
    // https://www.lipsum.com/ 에서 복사한 200자 이상 텍스트
    body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
    tags: ['가짜', '데이터'],
  }));
  Post.insertMany(posts, (err, docs) => {
    console.log(docs);
  });
}

* 그 다음에는 main.js에서 방금 만든 함수를 불러와 한번 호출해 주자.

[src/main.js]

require('dotenv').config();
import Koa from 'koa';
import Router from 'koa-router';
import bodyParser from 'koa-bodyparser';
import mongoose from 'mongoose';

import api from './api';
import createFakeData from './createFakeData';

// 비구조화 할당을 통해 process.env 내부 값에 대한 레퍼런스 만들기
const { PORT, MONGO_URI } = process.env;

mongoose
  .connect(MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true }) // useUnifiedTopology 추가
  .then(() => {
    console.log('Connected to MongoDB...');
    createFakeData();
  })
  .catch((e) => {
    console.error(e);
  });
  
  (...)

* 코드를 저장하고 서버가 재시작되면 터미널에 다음과 같은 메시지가 출력될 것이다.

* Compass를 통해 데이터가 잘 등록되었는지 확인해 보자.

데이터 등록 확인

* Compass에서 데이터가 보이지 않으면 우측 상단의 새로고침 버튼을 눌러 보자.

* 데이터가 잘 등록된 것을 확인했으면 createFakeData를 호출하는 코드를 main.js에서 지워 주자.


(2) 포스트를 역순으로 불러오기

* 페이지 기능을 구현하기에 앞서 포스트를 역순으로 불러오는 방법을 알아보겠다. 현재 list API에서는 포스트가 작성된 순서대로 나열되는데, 블로그에 방문한 사람에게 가장 최근 작성된 포스트를 먼저 보여 주는 것이 좋다.

* 이를 구현하려면 list API에서 exec()를 하기 전에 sort() 구문을 넣어 주면 된다.

* sort 함수의 파라미터는 { key : 1 } 형식으로 넣는데, key는 정렬(sorting)할 필드를 설정하는 부분이며, 오른쪽 값을 1로 설정하면 오름차순으로, -1로 설정하면 내림차순으로 정렬한다. 우리는 _id를 내림차순으로 정렬하고 싶으니 { _id: -1 }로 설정한다.

[src/api/posts/posts.ctrl.js]

/*
  GET /api/posts
*/
export const list = async (ctx) => {
  try {
    const posts = await Post.find()
      .sort({ _id: -1 }) // 내림차순 정렬
      .exec();
    ctx.body = posts;
  } catch (e) {
    ctx.throw(500, e);
  }
};

* 다시 Postman으로 list API를 호출해 보자. 가장 마지막으로 등록된 포스트가 맨 위에 나타난다.

GET http://localhost:4000/api/posts

포스트 번호를 보면 최신 순으로 정렬되어 표기된다.


(3) 보이는 개수 제한

* 이번에는 한 번에 보이는 개수를 제한해 보겠다. 개수를 제한할 때는 limit() 함수를 사용하고, 파라미터에는 제한할 숫자를 넣으면 된다. 예를 들어 열 개로 제한하려면 limit(10) 이라고 입력한다.

* list 함수의 코드를 다음과 같이 수정해 보자.

[src/api/posts/posts.ctrl.js]

/*
  GET /api/posts
*/
export const list = async (ctx) => {
  try {
    const posts = await Post.find()
      .sort({ _id: -1 }) // 내림차순 정렬
      .limit(10) // 한 번에 보여줄 게시물을 10개로 제한
      .exec();
    ctx.body = posts;
  } catch (e) {
    ctx.throw(500, e);
  }
};

* 이제 Postman으로 list API를 요청하면 최근 작성된 열 개의 포스트만 불러올 것이다.