Query parameters, the part of a URL after the ?, are how clients pass optional filtering, sorting, and pagination information. This lesson covers how Express parses them into req.query.
What Are Query Parameters?
A query string is a set of key=value pairs appended to a URL after a ?, separated by &. Express automatically parses this into a plain object available as req.query, no extra middleware required.
Unlike route parameters, query parameters are always optional by nature, a good API should behave sensibly whether or not any are provided.
Repeating the same key produces an array on req.query.
Bracket syntax (filter[status]=active) produces a nested object, via the qs library Express uses internally.
Missing query parameters are simply undefined, always provide sensible defaults.
Query parameters are always strings until you explicitly cast them.
Query Parameters Cheatsheet
Common filtering, sorting, and pagination patterns built on req.query.
URL
req.query
Use Case
/products?page=2&limit=20
{ page: '2', limit: '20' }
Pagination
/products?sort=-price
{ sort: '-price' }
Sorting (leading - for descending)
/products?category=shoes
{ category: 'shoes' }
Filtering
/products?tags=a&tags=b
{ tags: ['a', 'b'] }
Multi-value filtering
/products?q=running+shoes
{ q: 'running shoes' }
Free-text search
Pagination With Query Parameters
A typical paginated endpoint reads page and limit from the query string, applies sane defaults, and clamps them to reasonable bounds before using them.
Build filtering logic defensively, only apply a filter when the corresponding query parameter is actually present, so an endpoint still returns everything by default.
app.get('/products', (req, res) => {
let results = [...allProducts];
if (req.query.category) {
results = results.filter((p) => p.category === req.query.category);
}
if (req.query.sort === 'price') {
results.sort((a, b) => a.price - b.price);
}
res.json(results);
});
Common Mistakes
Comparing req.query.page to a number with === without casting it first, since it is always a string.
Not setting an upper limit on pagination size, letting a client request thousands of records at once.
Assuming a query parameter always exists instead of providing a sensible default.
Forgetting that repeated query keys produce arrays and can break code that expects a single string.
Key Takeaways
Express automatically parses the query string into req.query, no middleware needed.
All query values are strings or arrays of strings, cast them explicitly when needed.
Always provide defaults and reasonable limits for pagination parameters.
Apply filters conditionally so an endpoint behaves sensibly with no query parameters at all.
Pro Tip
Cap limit on paginated endpoints (e.g. Math.min(100, requestedLimit)) so a malicious or careless client can never force your API to return an unbounded number of records in one request.
You now know how to read and validate query parameters. Next, learn different patterns for structuring route handlers in the Route Handlers lesson.