uncategorized

페이징 방식에 의존하지 않는 페이지 API 설계하기

요약

Rest API의 HATEOAS 원칙을 적용하면 페이징 방식에 의존하지 않는 API를 구현할 수 있다. 첫 페이지에 접근할 수 있는 API만 프론트엔드에게 알려주고 다른 페이지에 접근하는 API는 첫 페이지에 접근하는 API의 응답 데이터에 동적으로 담겨있게 하자. 그러면 페이징 방식 변경에 따른 프론트엔드 변경이 생기지 않는다.

문제 상황

기리기리 서비스는 페이지 API를 제공해야 한다. 페이지 API는 일반적으로 쿼리 파라미터를 통해 다음과 같은 보고 싶은 페이지에 필요한 정보를 함께 전달한다.

  • 페이지 번호
  • 페이지 당 데이터 갯수
  • 정렬 기준 등…

문제는 페이지네이션의 구현 방법에 따라 쿼리 파라미터로 받아야 하는 정보가 달라지게 된다. 대표적으로 오프셋 기반 페이지네이션을 커서 기반 페이지네이션으로 바뀌게 되면 쿼리 파라미터로 현재 어디까지 읽었는 지를 전달해줘야 한다. (https://velog.io/@minsangk/%EC%BB%A4%EC%84%9C-%EA%B8%B0%EB%B0%98-%ED%8E%98%EC%9D%B4%EC%A7%80%EB%84%A4%EC%9D%B4%EC%85%98-Cursor-based-Pagination-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0)

즉 백엔드에서 구현을 바꾸면 쿼리 파라미터가 변경되면서 API에 변경이 생긴다. 현재 프로젝트에서는 프론트엔드와 백엔드가 함께 일하는 구조라 괜찮지만 만약 프로젝트가 끝나서 프론트엔드에게 변경을 요청하기 힘든 경우에는 어떨까? 만약 우리의 API를 수만명이 사용하고 있다면? API 변경을 통보하기 쉽지않을 것이다.

개선 방법

일단 페이지 API를 어떻게 사용하는 지 이해해보자. 기리기리 서비스에서는 누구나 첫 페이지부터 조회해서 다른 페이지로 이동할 때 페이지 번호를 클릭하거나 아니면 화살표를 클릭해서 이동할 것이다.

즉 첫 페이지를 조회하는 API는 반드시 노출된다. 첫 페이지를 조회하는 API는 다음과 같다.
equipments?size=16&page=0
여기서 판단하기를 첫 페이지 조회의 API는 페이지네이션 구현방법에 의존하지 않는다. 해당 API에 페이지네이션 구현 방법에 의존하는 데이터는 드러나지 않는다. 문제는 다음 페이지로 이동하는 경우에 문제가 될 수 있다.

오프셋 기반 페이지네이션으로 두번째 페이지를 조회하는 API는 다음과 같다.
equipments?size=16&page=1
커서 기반 페이지네이션으로 두번째 페이지를 조회하는 API는 다음과 같다.
equipments?size=16&cursor={마지막으로 읽은 위치}
즉 페이지네이션 구현에 의존하는 API가 됐다.

그렇다면 첫 페이지 조회 API만 공개하고 다른 페이지 조회는 공개하지 않는다면?

우리 서비스가 반드시 첫 페이지에 접근해서 다른 페이지로 이동하는 방식이므로 첫 페이지 조회 API만 공개하고 다른 페이지 접근하는 API는 첫 페이지 조회 API의 바디값에 동적으로 담아서 전달하면 된다.

즉 다음과 같이 응답해주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"endPoints": [
"/api/equipments?size=16&page=0&sort=id,DESC",
"/api/equipments?size=16&page=1&sort=id,DESC"
],
"page": 0,
"items": [
{
"id": 53,
"category": "VR",
"maker": "Meta",
"modelName": "Oculus Quest2",
"rentalQuantity": {
"totalQuantity": 6,
"remainingQuantity": 6
},
"imgUrl": "https://images.stockx.com/images/Oculus-Quest-2-128GB-VR-Headset-AU-Plug-899-00186-02.jpg?fit=fill&bg=FFFFFF&w=480&h=320&fm=webp&auto=compress&dpr=2&trim=color&updated_at=1675800692&q=75"
},
// 생략...
]
}

우리 서비스는 endPoints에 접근 가능한 다른 페이지의 API를 같이 응답해준다. 그러면 프론트엔드는 해당 API를 그대로 요청하면 해당 페이지를 조회할 수 있게 된다. 그리고 백엔드가 페이지네이션 구현 방법을 변경해도 프론트엔드는 변경 없이 endPoints을 통해 다른 페이지를 조회하면 된다.

결과

API 사용 형태를 분석하여 페이지네이션 구현에 의존하지 않는 첫 페이지 조회 API만 공개하고 다른 페이지 조회 API는 바디값에 넣어서 해당 API를 사용하도록 하여 프론트엔드에서는 페이지네이션 구현 방법에 대한 의존을 없앨 수 있었다.

Share