Pagination¶
External pagination lets your API return cursors to clients for stateless pagination.
Query Pagination¶
# Get first page
page1 = Order.query("customer-456").limit(10).page()
print(f"Items: {len(page1.items)}, Has more: {page1.has_more}")
# Get next page using cursor
if page1.has_more:
page2 = Order.query("customer-456").limit(10).page(start_key=page1.last_evaluated_key)
Scan Pagination¶
# First page
page1 = Product.scan().limit(25).page()
# Next page
if page1.has_more:
page2 = Product.scan().limit(25).page(start_key=page1.last_evaluated_key)
PageResult¶
The page() method returns a PageResult object:
| Attribute | Type | Description |
|---|---|---|
items |
list[Model] |
Items in the current page |
last_evaluated_key |
dict \| None |
Cursor for the next page |
has_more |
bool |
Whether more pages exist |
FastAPI Integration¶
from fastapi import FastAPI, Query
from typing import Any
from pydantic import BaseModel
app = FastAPI()
class PaginatedResponse(BaseModel):
items: list[dict[str, Any]]
next_cursor: dict[str, Any] | None
has_more: bool
@app.get("/orders/{customer_id}")
def get_orders(
customer_id: str,
limit: int = Query(default=20, le=100),
cursor: dict[str, Any] | None = None
) -> PaginatedResponse:
page = Order.query(customer_id).limit(limit).page(start_key=cursor)
return PaginatedResponse(
items=[order.model_dump() for order in page.items],
next_cursor=page.last_evaluated_key,
has_more=page.has_more
)
Security
Pagination cursors contain DynamoDB key values. If exposing them to clients, consider encrypting or signing them to prevent tampering.