Script Valley
Express.js: APIs and Middleware
Building RESTful APIsLesson 3.4

Pagination, filtering, and sorting in REST APIs

page and limit query params, skip and offset, sorting by field, filter by property, cursor pagination concept, totalPages calculation, query builder pattern

Pagination, Filtering, and Sorting

Production APIs never return entire datasets. Pagination, filtering, and sorting are controlled through query parameters.

Implementing all three

let products = Array.from({ length: 50 }, (_, i) => ({
  id: i + 1,
  name: `Product ${i + 1}`,
  category: i % 2 === 0 ? 'shoes' : 'bags',
  price: Math.round(Math.random() * 200) + 10
}));

app.get('/products', (req, res) => {
  let { page = 1, limit = 10, sort, category } = req.query;
  page = parseInt(page);
  limit = parseInt(limit);

  let result = [...products];

  // Filter
  if (category) result = result.filter(p => p.category === category);

  // Sort
  if (sort) result.sort((a, b) => a[sort] > b[sort] ? 1 : -1);

  // Paginate
  const total = result.length;
  const start = (page - 1) * limit;
  const data = result.slice(start, start + limit);

  res.json({
    data,
    meta: { page, limit, total, totalPages: Math.ceil(total / limit) }
  });
});

Always validate and cap the limit parameter: limit = Math.min(parseInt(limit), 100). Never let clients request unlimited records. Include meta.total and meta.totalPages so clients can render pagination UI without a second request.

Up next

How to handle async route handlers without crashing Express

Sign in to track progress