DevPath · Learn to code ESPTEN

Routes, REST and API design

Pagination, filtering and sorting

Why paginate

A listing can have thousands of items. Returning them all is slow and expensive. The standard solution is to expose parameters in the query string that the client combines to request exactly what it needs.

Filtering

Filtering reduces the collection to those that meet a condition:

// GET /products?category=books
let list = products;
if (req.query.category) {
  list = list.filter((p) => p.category === req.query.category);
}

Sorting

sort indicates the field, with a - in front for descending (?sort=-price). The comparator must return 0 on ties (otherwise the order becomes unstable) and work the same with numbers and with text:

// GET /products?sort=price   or   ?sort=-price (descending)
if (req.query.sort) {
  const desc = req.query.sort.startsWith("-");
  const field = desc ? req.query.sort.slice(1) : req.query.sort;
  list = [...list].sort((a, b) => {
    if (a[field] < b[field]) return desc ? 1 : -1;
    if (a[field] > b[field]) return desc ? -1 : 1;
    return 0; // tie: they keep their order
  });
}

Pagination

With page (page, starting at 1) and limit (page size) you compute the slice of the array with slice:

// GET /products?page=2&limit=10
const page = Number(req.query.page) || 1;
const limit = Number(req.query.limit) || 10;
const start = (page - 1) * limit;
const pageItems = list.slice(start, start + limit);
res.json({ page, limit, total: list.length, data: pageItems });

The usual order is: filter → sort → paginate. This way you paginate over the already filtered and sorted result.

Put this into practice

DevPath is a hands-on course: you read the theory here; in the app you put it into practice with exercises that really run, offline.

Start free in the app →
← REST design: resources and statusesView the module →