Query Parameters
Part of the Backend Developer Roadmap
In short
Filters, search, sorting and pagination all live after the ? in a URL. Query parameters let the client fine-tune what it gets back from the same endpoint.
Key-value pairs appended to a URL (`?page=2&sort=price`) captured into `req.query` — the standard way to handle filtering, sorting and pagination options.

Think of it like this
Customising your chai
It's still a cutting chai, but you tell the bhaiya: less sugar, extra adrak, no elaichi. Same order, your tweaks. GET /products?sort=price&limit=10 is the same endpoint with your preferences added at the end.
Watch it happen
Paginating with ?page=2&limit=3
1/5There are 8 products. The client asks for page 2 with 3 items per page.
The big ideas
What you need to know
For reading, not identity
Use params for which resource (/products/7). Use query for how to show a list (?sort=price).
Strings, every time
?limit=10 gives "10". Convert, check the range, and use a default when it's missing.
Cap the limit
Never trust ?limit=100000. Set a maximum like 100 so one request can't load your whole table.
Allow-list sort fields
Only accept known values like price or name for ?sort, never pass them straight into a query.
See it in code
Walk through the code
1const SORTABLE = new Set(["price", "name", "createdAt"]);2 3app.get("/products", async (req, res) => {4 const page = Math.max(1, Number(req.query.page) || 1);5 const limit = Math.min(100, Math.max(1, Number(req.query.limit) || 20));6 const sort = SORTABLE.has(req.query.sort) ? req.query.sort : "createdAt";7 const search = String(req.query.q ?? "").trim();8 9 const { items, total } = await db.products.list({10 search, sort, skip: (page - 1) * limit, take: limit,11 });12 13 res.json({ items, page, limit, total, pages: Math.ceil(total / limit) });14});1/4An allow-list of fields clients may sort by.
Number("abc") is NaN, and NaN || 1 gives 1. That one trick gives every bad value a safe default.
Save yourself the pain
Common mistakes
Oops
Using req.query.limit directly, so ?limit=999999 loads everything.
Do this instead
Convert it to a number and clamp it between a minimum and maximum you choose.
Oops
Putting secrets like ?apiKey=... in the query string.
Do this instead
Query strings end up in logs and browser history. Send secrets in headers like Authorization.
Your mission
Filter, sort, paginate
Quick check
Which belongs in a query parameter rather than a route parameter?
Go deeper
- 1Build a search endpoint reading filters from `req.query`.
- 2Set sensible defaults for missing query params, e.g. a default page size.
- 3Validate and sanitize query params before using them in a database query.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.