DynamoDB의 페이지네이션
DynamoDB는 한 번의 호출로 "모든" 결과를 반환하지 않습니다. Query나 Scan은 최대 1 MB의 데이터를 반환한 뒤, 이어서 시작할 수 있는 LastEvaluatedKey를 건네줍니다. 페이지네이션을 제대로 하려면 카운터가 아니라 그 키를 기준으로 루프를 돌아야 합니다.
루프
let key;
do {
const out = await client.send(new QueryCommand({...params, ExclusiveStartKey: key}));
process(out.Items);
key = out.LastEvaluatedKey;
} while (key);LastEvaluatedKey가 undefined이면 끝에 도달한 것입니다. 다음 조각을 가져오려면 이를 ExclusiveStartKey로 다시 전달하세요.
제어 흐름은 키가 없을 때만 빠져나가는 단일 루프입니다:
매 회차마다 반환된 키에서 이어가거나 멈추거나 둘 중 하나입니다 — 카운터는 없습니다.
Limit은 페이지 크기가 아닙니다
Limit은 DynamoDB가 평가하는 항목 수를 제한할 뿐, FilterExpression 적용 후 반환하는 수를 제한하지 않습니다. 필터 뒤에 있는 Limit: 25 쿼리는 3개의 항목을 반환하면서도 여전히 LastEvaluatedKey를 건넬 수 있습니다 — 페이지가 짧아 보이더라도 키가 빌 때까지 계속 페이지를 넘겨야 합니다. 비어 있지 않은 LastEvaluatedKey 역시 더 많은 일치 항목을 절대 보장하지 않습니다. 오직 없는 키만이 끝에 도달했음을 증명합니다.
SDK가 페이지네이션하게 하기
두 SDK 모두 위 루프를 감싸므로 페이지를 직접 순회할 수 있습니다:
// AWS SDK for JavaScript v3
import {paginateQuery} from '@aws-sdk/lib-dynamodb';
for await (const page of paginateQuery({client}, params)) {
process(page.Items);
}# boto3
paginator = client.get_paginator('query')
for page in paginator.paginate(**params):
process(page['Items'])페이지 번호는 없습니다
DynamoDB에는 전체 개수도, 임의 페이지 접근도 없습니다 — 커서를 다시 재생하지 않고는 "7페이지"로 건너뛰거나 뒤로 갈 수 없습니다. 번호가 매겨진 페이지가 아니라 무한 스크롤 / "더 보기"를 중심으로 UI를 설계하세요. (Select: 'COUNT' 쿼리도 개수를 세기 위해 일치한 모든 항목을 읽고 — 그에 대해 과금합니다.)
API를 위한 무상태 커서
LastEvaluatedKey는 마지막 항목의 키 속성일 뿐입니다. 이를 base64로 인코딩하여 불투명한 nextToken으로 클라이언트에 건네고, 다음 요청에서 다시 ExclusiveStartKey로 디코딩하세요. 서버 측 커서 상태가 없습니다.
그 token은 DynamoDB-JSON입니다 — DynamoDB-JSON 변환기로 직접 살펴보거나 손수 만들어 보세요. 그리고 Scan을 우회하려고 페이지를 넘기고 있다면, 보통 인덱스를 추가하라는 신호입니다.
DynoTable을 사용해 커서를 대신 추적하면서 쿼리 결과를 시각적으로 페이지 넘겨 보세요.