Skip to main content

Command Palette

Search for a command to run...

URL Parameters vs Query Strings in Express.js

Updated
7 min read
URL Parameters vs Query Strings in Express.js

What URL Parameters Are

A URL parameter is a named placeholder inside a route path that captures a specific segment of the URL. It is part of the path itself, not appended after it.

Consider this URL

GET /users/42

Here, 42 is the value occupying a dynamic segment of the path. In Express, that segment is defined in the route as :id, making 42 the value of the id parameter.

URL parameters represent identity. They point to a specific, individual resource. In the example above, the intent is clear: retrieve the user whose ID is 42. The path would be meaningless without that value.

Other real-world examples

GET /products/keyboard-mechanical    -- a specific product
GET /orders/ORD-2026-9981            -- a specific order
GET /posts/how-react-virtual-dom-works  -- a specific blog post

In each case, the dynamic segment identifies which resource the client wants. Remove that segment and the request loses its target entirely.

URL parameters are required by definition. A route defined as /users/:id will not match the path /users at all. The parameter must be present for the route to match.

What Query Parameters Are

Query parameters are key-value pairs appended to the end of a URL after a ?. Multiple query parameters are separated by &.

GET /users?role=admin&active=true

Here, role=admin and active=true are two query parameters. They do not change which resource is being accessed. They modify how the request is processed, what data is returned, or how results are filtered.

Query parameters represent options, not identity. In the example above, the client is asking for users, with the additional instruction to filter by role and active status.

Other real-world examples

GET /products?category=electronics&sort=price&order=asc
GET /posts?tag=javascript&page=2&limit=10
GET /users?search=alice

None of these query strings identify a single resource. They describe how to shape or filter the collection being returned.

Query parameters are optional by nature. A route defined as /users will match both /users and /users?role=admin. The absence of a query parameter is handled in the route logic, not by route matching.

Differences Between Them

Dimension URL Parameters Query Parameters
Location in URL Inside the path: /users/:id After the path: /users?role=admin
Purpose Identify a specific resource Filter, sort, paginate, or modify results
Required Yes - route will not match without them No - always optional
Accessed via req.params req.query
Example /users/42 /users?role=admin
Typical use Resource identity Search, filter, pagination, configuration

The clearest way to think about the distinction is this

  • If removing the value makes the request lose its target, it is a URL parameter.

  • If removing the value just changes what is returned, it is a query parameter.

A request for /users/42 without the 42 has no meaning. A request for /users without ?role=admin still makes sense - it just returns all users instead of filtered ones.

Accessing URL Parameters in Express

URL parameters are defined in the route path using a colon followed by the parameter name. Express captures the value from the incoming URL and makes it available on req.params.

Defining a Route with a Parameter

app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  res.json({ userId });
});

A request to GET /users/42 would produce

{ "userId": "42" }

Note that req.params.id is always a string, even if the value looks like a number. Convert it explicitly when needed

const userId = parseInt(req.params.id, 10);

Multiple Parameters

A route can contain more than one parameter

app.get('/teams/:teamId/members/:memberId', (req, res) => {
  const { teamId, memberId } = req.params;
  res.json({ teamId, memberId });
});

A request to GET /teams/5/members/99 would produce

{ "teamId": "5", "memberId": "99" }

Each named segment in the path becomes a key on req.params with its corresponding URL value.


Accessing Query Strings in Express

Query parameters require no special route definition. Express parses the query string of every incoming request automatically and exposes it on req.query as a plain JavaScript object.

Reading Query Parameters

app.get('/users', (req, res) => {
  const role = req.query.role;
  const active = req.query.active;

  res.json({ role, active });
});

A request to GET /users?role=admin&active=true would produce

{ "role": "admin", "active": "true" }

Like route params, all query values are strings. If you need a boolean or number, parse the value explicitly

const active = req.query.active === 'true';
const page = parseInt(req.query.page, 10) || 1;

Handling Missing Query Parameters

Because query parameters are optional, always account for the case where a parameter is absent. Use a default value or a conditional check before using the value in logic.

app.get('/products', (req, res) => {
  const category = req.query.category || 'all';
  const page = parseInt(req.query.page, 10) || 1;
  const limit = parseInt(req.query.limit, 10) || 20;

  res.json({ category, page, limit });
});

A request to GET /products with no query string would respond with

{ "category": "all", "page": 1, "limit": 20 }

A request to GET /products?category=electronics&page=2 would respond with

{ "category": "electronics", "page": 2, "limit": 20 }

This pattern makes routes flexible without making them fragile.

When to Use Params vs Query

Choosing between URL parameters and query strings is not a matter of preference. There is a practical rule that applies consistently across REST API design.

Use URL Parameters When

You are identifying a specific resource.

If the value is required to locate what the client is asking for, it belongs in the path.

GET /users/42           -- fetch user 42
GET /posts/express-101  -- fetch a specific post
GET /invoices/INV-0091  -- fetch a specific invoice

Omitting the value from the path makes the request ambiguous or unroutable. Express will not even match the route.

Use Query Parameters When

You are modifying, filtering, or configuring how data is returned.

If the value is optional context that shapes the response rather than identifies the resource, it belongs in the query string.

GET /users?role=admin              -- filter users by role
GET /products?sort=price&order=asc -- sort products
GET /posts?page=2&limit=10         -- paginate results
GET /logs?from=2024-01-01&to=2024-01-31  -- filter by date range

The route still makes sense without these values. The query parameters are instructions for how to process the request, not what to target.

A Combined Example

Both can appear in the same request when the use case calls for it:

GET /users/42/orders?status=pending&page=1

Here, /users/42/orders uses two URL parameters to identify a specific resource collection - the orders belonging to user 42. The query string then filters that collection to show only pending orders on the first page.

This is a clean and semantically correct URL structure. The path tells Express what is being accessed. The query string tells it how to shape the response.

Conclusion

URL parameters and query strings solve different problems. Parameters identify resources. Query strings configure how those resources are returned.

Getting this distinction right makes your API routes more readable, more predictable, and easier for other developers to consume. It also aligns with how REST APIs are conventionally designed, which reduces friction for anyone working with your endpoints.

More from this blog