위 글에서 페이지네이션의 두 가지 구현 방식을 알아보았다. 이해를 돕기 위해 이번 글에서는 Java 환경에서 커서 기반으로 페이지네이션을 구현해보겠다.
가장 먼저 페이지네이션을 적용한 데이터들을 담을 응답 객체를 정의해야 한다.
import java.util.List;
import java.util.function.Function;
public record PageInfo<T>(
String pageToken,
List<T> data,
boolean hasNext
) {
public static <T> PageInfo<T> of(
List<T> data,
int expectedSize,
Function<T, Object> pageTokenFunction
) {
if (data.size() <= expectedSize) {
return new PageInfo<T>(null, data, false);
}
var lastValue = data.get(expectedSize - 1);
var pageToken = pageTokenFunction.apply(lastValue).toString();
return new PageInfo<T>(pageToken, data.subList(0, expectedSize), true);
}
}
<T>: 제너릭 타입을 통해 선언 시 구체 타입을 정할 수 있게 한다.PageInfo<PostDetailResponse>pageToken: 다음 페이지 요청 기준이 되는 cursor 값.List<T> data: 응답 데이터들이 담길 곳.hasNext: 다음 페이지 존재 여부. null일 시 첫 페이지 조회.expectedSize: 다음 페이지 여부를 확인하기 위한 페이지 크기(기대하는 페이지 크기보다 작으면 다음 페이지가 없다는 뜻)Function<T, Object> pageTokenFunction: T 타입을 받아 Object로 변환 후, 문자열 형태로 pageToken 생성ex)
PageInfo.of(data, DEFAULT_PAGE_SIZE, PostDetailResponse::createdAt);
PostDetailResponse를 받아서 createdAt으로 변환해 pageToken 생성.
쿼리를 작성하는 부분은 구현 환경에 따라 다르니 sql 형식으로 작성하겠다.
SELECT 응답 객체 (위의 T타입에 해당하는 객체)
FROM ~
ORDER BY 정렬기준 (id, createdAt 등등)
WHERE id > pageToken
LIMIT pageSize + 1 (정해논 페이지 크기보다 하나 더 가져와서 다음 pageToken으로 사용)
이렇게 조회해온 데이터로 PageInfo의 of메서드를 통해 생성해 응답을 내려주면 된다.
*페이지네이션은 도메인과 클라이언트 개발자와의 소통이 매우 중요하다고 생각한다. 언제나 상황에 적절한 방법을 쓰자.