Route Parameters and Query Strings

beginner
12 min

Route Parameters and Query Strings

Static routes like /about only get you so far. Real applications need URLs that carry data: /users/42, /products/laptops/8, or /search?q=express&page=2. Express gives you two tools for this: route parameters for identifying resources and query strings for optional modifiers. This lesson covers both, plus validation basics.

Route Parameters

A route parameter is a named URL segment that starts with a colon. Whatever the client puts in that position is captured into req.params:

js
app.get('/users/:id', (req, res) => { res.send('User ID is ' + req.params.id); });

Requesting /users/42 responds with 'User ID is 42', and /users/alice responds with 'User ID is alice'. The parameter matches a single segment, so /users/42/posts does not match this route.

Multiple Parameters

You can capture several segments at once. Each name becomes a property on req.params:

js
app.get('/products/:category/:productId', (req, res) => { const { category, productId } = req.params; res.json({ category, productId }); });

A request to /products/laptops/8 yields { category: 'laptops', productId: '8' }. Note that captured values are always strings, even when they look like numbers. Convert with Number() before doing math or database lookups by numeric ID.

A Realistic Lookup Example

Here is a pattern you will use constantly: find an item by ID and return 404 when it does not exist.

js
const users = [ { id: 1, name: 'Aisha' }, { id: 2, name: 'Marco' }, ]; app.get('/api/users/:id', (req, res) => { const id = Number(req.params.id); const user = users.find(u => u.id === id); if (!user) { return res.status(404).json({ error: 'User not found' }); } res.json(user); });

The early return is important. Without it, execution would continue and try to send a second response.

Query Strings

Everything after the ? in a URL is the query string: /search?q=express&page=2. Express parses it into req.query automatically:

js
app.get('/search', (req, res) => { const q = req.query.q || ''; const page = Number(req.query.page) || 1; res.json({ query: q, page }); });

Query values are also strings and, crucially, always optional. Your handler must supply sensible defaults, as the example does with an empty search and page 1.

Params or Query: Which One?

Use a route parameter when the value identifies the resource itself: /users/42 means user number 42; without the ID the URL is meaningless. Use the query string for optional instructions about how to return data: sorting, filtering, pagination, or search terms. A good mental test: if removing the value should produce a 404, it belongs in the path; if removing it should just change the output, it belongs in the query.

Validating Input

Never trust URL input. A quick guard prevents confusing errors deeper in your code:

js
app.get('/api/orders/:id', (req, res) => { const id = Number(req.params.id); if (!Number.isInteger(id) || id <= 0) { return res.status(400).json({ error: 'id must be a positive integer' }); } res.json({ orderId: id }); });

Later in the series we will move validation into reusable middleware.

Key Takeaways

  • :name in a path captures a URL segment into req.params.name.
  • req.query holds parsed query string values; both params and query are strings.
  • Use params for identity, query strings for options like filters and pagination.
  • Return 404 for missing resources and 400 for malformed input, with early returns.
  • Always provide defaults for optional query values.

Next lesson: Middleware Explained, the concept that makes Express truly powerful.

Route Parameters and Query Strings - Express.js | CodeYourCraft | CodeYourCraft