paginated API test (1)

unow30·2020년 12월 27일
0

experss

목록 보기
7/8

다음편

1. 기본 서버(express)와 설정

//package.json
{
  "name": "api",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js"
  },
  "author": "me",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "nodemon": "^2.0.6"
  }
}
//index.js
const express = require("express");
const app = express();
const port = 3000;

const user = [
    { id: 1, name: "user1" },
    { id: 2, name: "user2" },
    { id: 3, name: "user3" },
    { id: 4, name: "user4" },
    { id: 5, name: "user5" },
    { id: 6, name: "user6" },
    { id: 7, name: "user7" },
    { id: 8, name: "user8" },
    { id: 9, name: "user9" },
    { id: 10, name: "user10" },
    { id: 11, name: "user11" },
    { id: 12, name: "user12" },
    { id: 13, name: "user13" },
]
app.get("/users", (req, res) => {
    res.json(user)
})

app.listen(port, () => {
    console.log(`this server listening to ${3000} port`);
})

테스트 도중 알게된 확정 프로그램

  • REST-Client: vscode에서 rest url 요청을 보내 결과를 확인할 수 있다. .rest파일에서 작성하면 실행된다.
    아래 이미지를 확인한다.(테스트 후 user -> users로 바꾸고 id 수도 13개로 늘렸다.)

2. 페이지 설정하기

  • url 주소에 페이지, 페이지 당 데이터 수를 표시한다.
  • index.js에도 페이지 설정에 접근 가능한 경로를 작성한다.
//index.js
//윗부분 생략
app.get("/users", (req, res) => {
    const page = req.query.page
    const limit = req.query.limit

    const startIndex = (page - 1) * limit
    const endIndex = page * limit

    const resultUsers = users.slice(startIndex, endIndex);

    // res.json(users)
    res.json(resultUsers)
})

//request.rest
GET http://localhost:3000/users?page=1&limit=5
  • 총 13개의 id를 1 페이지마다 5개씩 출력할 것이다.

  • startIndex와 endIndex를 users.slice의 인자로 넣으면, 처음 1페이지일 때는 둘의 값이 (0, 5)가 나올 것이다. 이는 users의 배열값을 인덱스 0번부터 5번까지 slice한다는 뜻이 되며 이를 테스트하면 확인할 수 있다.

  • 실행 결과는 다음과 같다. page의 값을 2, 3으로 변경하면 변경된 값이 나온다.

3. previous, next 페이징 만들기

  • users의 페이징 결과를 객체에 담아서 전송할 것이다. 그리고 그 안에 이전 페이지와 다음 페이지를 지정하여 출력할 것이다.
  • 먼저 limit를 3으로 하여 페이징이 여러 번 일어나게 한다.
//request.rest
GET http://localhost:3000/users?page=1&limit=3
//index.js
//윗부분 생략
app.get("/users", (req, res) => {
    const page = req.query.page
    const limit = req.query.limit

    const startIndex = (page - 1) * limit
    const endIndex = page * limit

    const results = {}
    results.result = users.slice(startIndex, endIndex);

    // res.json(users)
    res.json(results)
})
  • results 객체에 result 속성이 생성되고, 그 안에 users.slice값이 들어간다.
    request 요청을 보내면 결과값이 results의 result에 담겨있는 것을 볼 수 있다.

  • 이제 results 객체 안에 추가정보(previous, next)를 넣을 것이다. 각각 page를 -1, +1 시켜준다.

app.get("/users", (req, res) => {
    const page = req.query.page
    const limit = req.query.limit

    const startIndex = (page - 1) * limit
    const endIndex = page * limit

    const results = {}

    results.previous = {
        previous: page - 1,
        limit: limit
    }

    results.next = {
        next: page + 1,
        limit: limit
    }
    results.result = users.slice(startIndex, endIndex);

    // res.json(users)
    res.json(results)
})
  • 이 상태에서 테스트를 실행하면 next, previous의 페이지 값이 이상하게 나온다.
//request.rest
GET http://localhost:3000/users?page=1&limit=3 일때 previous는 0, next는 11이 나온다.
GET http://localhost:3000/users?page=2&limit=3 일때 previous는 1, next는 21이 나온다.
GET http://localhost:3000/users?page=3&limit=3 일때 previous는 2, next는 31이 나온다.
  • 문제는 page+1을 하면 변수+1, 산술계산이 아니라 문자열 표기가 되버리는 것이다. req.query.page의 값이 문자열 "1" "2" "3"이 되기 때문에 빼기는 계산되는데 더하기는 문자열의 나열이 되기 때문이다.
  • page와 limit를 parseInt로 바꿔 숫자 데이터가 되도록 한다.
app.get("/users", (req, res) => {
    const page = parseInt(req.query.page)
    const limit = parstInt(req.query.limit)

    const startIndex = (page - 1) * limit
    const endIndex = page * limit

    const results = {}

    results.previous = {
        previous: page - 1,
        limit: limit
    }

    results.next = {
        next: page + 1,
        limit: limit
    }
    results.result = users.slice(startIndex, endIndex);

    // res.json(users)
    res.json(results)
})

4. 데이터가 없는 previous, next 속성 제거하기

  • page = 1일 때는 previous가 0이 되므로 접근할 수 있는 정보가 없다. 마찬가지로 마지막 페이지를 요청할 때 마지막 페이지+1에는 원하는 정보가 없다. 이런 데이터를 results에 previous나 next로 표현하면 혼동이 일어날 수 있다. if 분기를 이용해 이런 정보를 없에는 방법을 보여준다.
//page 1일때 previous 경로로 이동해도 아무런 값이 없다.
{
  "previous": {
    "previous": 0,
    "limit": 3
  },
  "next": {
    "next": 2,
    "limit": 3
  },
  "result": [
    {
      "id": 1,
      "name": "user1"
    },
    {
      "id": 2,
      "name": "user2"
    },
    {
      "id": 3,
      "name": "user3"
    }
  ]
}

//page = 5일때 마지막 데이터가 나온다. 하지만 next경로에는 아무런 값이 없다.
{
  "previous": {
    "previous": 4,
    "limit": 3
  },
  "next": {
    "next": 6,
    "limit": 3
  },
  "result": [
    {
      "id": 13,
      "name": "user13"
    }
  ]
}
//index
//이전 내용 생략
app.get("/users", (req, res) => {
    const page = parseInt(req.query.page)
    const limit = parseInt(req.query.limit)

    const startIndex = (page - 1) * limit
    const endIndex = page * limit

    const results = {}



    if (startIndex > 0) {
        results.previous = {
            previous: page - 1,
            limit: limit
        }
    }
    if (endIndex < users.length)
        results.next = {
            next: page + 1,
            limit: limit
        }
    results.result = users.slice(startIndex, endIndex);

    // res.json(users)
    res.json(results)
})
  • 이제 startIndex가 0보다 같거나 작으면 previous가 생성되지 않는다. endIndex가 users.length(users가 13개이다)보다 크거나 같다면 데이터가 출력되지 않는다.
    page=1이면 previous가 없다.page가 5이면 next가 없다.(마지막 남은 13번째 유저만 나온다.page1, limit 13이면 모든 데이터가 나오고 previous, next가 없다.

0개의 댓글