Skip to main content

Command Palette

Search for a command to run...

URL Parameters vs Query Strings in Express.js

Published
6 min read
URL Parameters vs Query Strings in Express.js

Your API needs to receive data from users. Express lets you pass data through the URL in two different ways: URL parameters and query strings. They look different, work differently, and have different purposes.

URL Parameters: Part of the Route

URL parameters are placeholders in the route path. They're required and define the resource you're accessing.

Consider these examples:

/users/123          - get user with ID 123
/posts/456/comments - get comments for post 456
/products/789/reviews - get reviews for product 789

The numbers and identifiers are URL parameters. They identify which specific resource you want.

In Express, you define parameters with a colon:

import express from 'express';

const app = express();

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

app.get('/posts/:postId/comments/:commentId', (req, res) => {
  const postId = req.params.postId;
  const commentId = req.params.commentId;
  res.json({ postId, commentId });
});

app.listen(3000);

When a request comes in, Express extracts the parameter values and places them in req.params.

Usage examples:

  • GET /users/123req.params.id = "123"

  • GET /posts/456/comments/789req.params.postId = "456", req.params.commentId = "789"

Query Strings: Optional Filters and Options

Query strings come after a question mark in the URL. They're optional and add filtering or modification options.

Consider these examples:

/users?role=admin           - filter users by role
/products?sort=price&limit=10 - sort by price, limit to 10 results
/search?q=node&lang=en      - search for "node" in English

In Express, query strings are available in req.query:

import express from 'express';

const app = express();

app.get('/users', (req, res) => {
  const role = req.query.role;
  const status = req.query.status;
  res.json({ message: `Getting users`, role, status });
});

app.get('/search', (req, res) => {
  const q = req.query.q;
  const limit = req.query.limit;
  res.json({ search: q, limit });
});

app.listen(3000);

Usage examples:

  • GET /users?role=adminreq.query.role = "admin"

  • GET /search?q=javascript&limit=20req.query.q = "javascript", req.query.limit = "20"

Parameters vs Query Strings: Key Differences

Aspect URL Parameters Query Strings
Purpose Identify resource Filter/modify results
Required Yes No
Syntax /users/123 /users?role=admin
Express req.params req.query
Example Get specific user Get users matching criteria
Multiple values Hard to add Easy with &

Real-World Examples

URL Parameters: Identify the exact resource you want

app.get('/users/:id', (req, res) => {
  // GET /users/123
  // Retrieve THE user with ID 123
});

app.get('/posts/:postId/comments/:commentId', (req, res) => {
  // GET /posts/456/comments/789
  // Get specific comment 789 in specific post 456
});

Query Strings: Filter or modify what you're retrieving

app.get('/users', (req, res) => {
  // GET /users?role=admin&status=active
  // Get all users, but filter by role and status
});

app.get('/posts', (req, res) => {
  // GET /posts?sort=date&limit=10&skip=20
  // Get posts, sorted by date, 10 per page, starting from position 20
});

Combining Both

You can use both parameters and query strings together:

import express from 'express';

const app = express();

app.get('/users/:id/posts', (req, res) => {
  const userId = req.params.id;
  const sort = req.query.sort;
  const limit = req.query.limit;
  
  res.json({
    message: `Getting posts for user ${userId}`,
    sort,
    limit
  });
});

app.listen(3000);

Examples:

  • GET /users/123/posts → User 123's posts

  • GET /users/123/posts?sort=date → User 123's posts sorted by date

  • GET /users/123/posts?sort=date&limit=10 → User 123's 10 most recent posts

Multiple Query Parameters

When you have multiple query parameters, separate them with &:

app.get('/search', (req, res) => {
  const query = req.query.q;
  const lang = req.query.lang;
  const category = req.query.category;
  
  res.json({ query, lang, category });
});

Usage:

GET /search?q=javascript&lang=en&category=tutorial
→ query = "javascript", lang = "en", category = "tutorial"

Query Parameters with Arrays

You can pass multiple values for the same parameter:

app.get('/products', (req, res) => {
  const colors = req.query.color;
  res.json({ colors });
});

Usage:

GET /products?color=red&color=blue&color=green
→ colors = ["red", "blue", "green"]

Type Conversion

Query parameters always come as strings. If you need numbers, convert them:

import express from 'express';

const app = express();

app.get('/products', (req, res) => {
  const limit = parseInt(req.query.limit) || 10;
  const skip = parseInt(req.query.skip) || 0;
  
  res.json({ limit, skip });
});

app.listen(3000);

Without conversion, req.query.limit is the string "20", not the number 20.

When to Use Each

Use URL parameters when:

  • Identifying a specific resource

  • The value is required

  • Following REST principles for resource identification

  • Examples: user ID, post ID, product ID

Use query strings when:

  • Filtering results

  • Sorting or paginating

  • The value is optional

  • Adding modifiers or options

  • Examples: role, category, sort order, page number

REST API Best Practices

A well-designed REST API uses both appropriately:

import express from 'express';

const app = express();

// Get all users (with optional filters)
app.get('/users', (req, res) => {
  const role = req.query.role;
  const status = req.query.status;
  // Retrieve users, optionally filtered by role and status
});

// Get specific user
app.get('/users/:id', (req, res) => {
  const userId = req.params.id;
  // Retrieve specific user by ID
});

// Get posts for a specific user (with optional sorting)
app.get('/users/:userId/posts', (req, res) => {
  const userId = req.params.userId;
  const sort = req.query.sort;
  // Retrieve posts for user, optionally sorted
});

// Get specific comment on specific post by specific user
app.get('/users/:userId/posts/:postId/comments/:commentId', (req, res) => {
  const { userId, postId, commentId } = req.params;
  // Retrieve specific comment
});

app.listen(3000);

Common Mistakes

Mistake 1: Using parameters when query strings make sense

// Wrong - parameters for filters
app.get('/users/:role/:status', (req, res) => {
  // URL becomes /users/admin/active
  // Hard to add more filters
});

// Better - query strings for filters
app.get('/users', (req, res) => {
  // URL is /users?role=admin&status=active
  // Easy to add/remove filters
});

Mistake 2: Forgetting to convert query parameters to numbers

app.get('/products', (req, res) => {
  const limit = req.query.limit; // This is a string!
  const results = db.getProducts().slice(0, limit);
  // limit as string might not slice correctly
});

Key Takeaways

  • URL parameters identify a specific resource and go in the route path

  • Query strings are optional filters and go after the question mark

  • Parameters are required and part of the route definition

  • Query strings are optional and make URLs flexible

  • Access parameters via req.params and query strings via req.query

  • Combine both for powerful, flexible APIs

  • Use parameters for identification, query strings for filtering

Mastering both gives you the tools to build flexible, standard REST APIs that users can intuitively understand.

URL Parameters vs Query Strings in Express.js