API Developmentintermediate
Implement cursor-based or offset pagination
API Pagination
Implement cursor-based or offset pagination
Implement cursor-based and offset pagination.
Instructions
Offset Pagination (simple, good for < 100K records)
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const page = Math.max(1, parseInt(searchParams.get('page') ?? '1'));
const limit = Math.min(100, Math.max(1, parseInt(searchParams.get('limit') ?? '20')));
const [items, total] = await Promise.all([
db.item.findMany({ skip: (page - 1) * limit, take: limit, orderBy: { id: 'desc' } }),
db.item.count(),
]);
return Response.json({
data: items,
meta: { page, limit, total, totalPages: Math.ceil(total / limit), hasMore: page * limit < total },
});
}
Cursor Pagination (better for large datasets, real-time data)
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const cursor = searchParams.get('cursor');
const limit = Math.min(100, parseInt(searchParams.get('limit') ?? '20'));
const items = await db.item.findMany({
take: limit + 1, // fetch one extra to check hasMore
...(cursor && { cursor: { id: cursor }, skip: 1 }),
orderBy: { id: 'desc' },
});
const hasMore = items.length > limit;
if (hasMore) items.pop();
return Response.json({
data: items,
meta: { nextCursor: hasMore ? items[items.length - 1].id : null, hasMore },
});
}
When to Use Which
- Offset: admin panels, search results, < 100K records
- Cursor: feeds, timelines, large datasets, real-time data