# URL Parameters vs Query Strings in Express.js

Table of Contents

1.  What are URL Parameters?
    
2.  What are Query Strings?
    
3.  Differences Between Them
    
4.  Accessing Params in Express
    
5.  Accessing Query Strings in Express
    
6.  When to Use Which
    

![](https://cdn.hashnode.com/uploads/covers/696f9f5589255b82f81f6b17/7563055c-3430-47c5-886f-5d532f6bbde1.png align="center")

## 01 — URL Parameters - What are URL Parameters?

A URL parameter is a **named placeholder inside the URL path itself**. It identifies a specific resource — like a user, a product, or a post. You can think of it as the ID card of whatever you're looking for.

In Express, you define a URL parameter by putting a colon before the name in your route:

```javascript
// :userId is the parameter — it will match anything in that position
app.get('/users/:userId', (req, res) => {
  res.send(`Fetching user ${req.params.userId}`)
})
```

Now if someone visits `/users/42`, Express knows that `42` is the value for `:userId`. You're essentially saying: *"Whatever comes after /users/ — that's my identifier."*

> **Think of params as identifiers**URL parameters are for pointing at *one specific thing*. A user profile. A blog post. A product page. If you can say "give me this exact resource," you're using a param.

* * *

## 02 — Query Strings - What are Query Strings?

A query string is a set of **key=value pairs that come after a** `?` **in the URL**. They don't point to a resource — they *filter, sort, or modify* what gets returned. Multiple pairs are joined with `&`.

```plaintext
/products?category=shoes&sort=price&limit=20
           ↑            ↑          ↑
         filter        sort       pagination
```

In Express, you don't declare query strings in the route at all — they're automatically available on `req.query` for any route:

```plaintext
app.get('/products', (req, res) => {
  const { category, sort, limit } = req.query
  // category → 'shoes', sort → 'price', limit → '20'
  res.send({ category, sort, limit })
})
```

> 🎯
> 
> **Think of query strings as filters**Query strings are for modifying the response — search terms, sort order, page number, date ranges. If you can remove them and still get *a* response (just less filtered), they're query strings.

* * *

## 03 — Differences - Differences Between Them

![](https://cdn.hashnode.com/uploads/covers/696f9f5589255b82f81f6b17/89c02edf-178b-4571-9e27-3995921a8ccb.png align="center")

* * *

## 04 — Express Code - Accessing Params in Express

You read URL parameters using `req.params`. Express populates this object automatically based on what you defined in the route..

```plaintext
// Route definition
app.get('/users/:userId', (req, res) => {
  const id = req.params.userId
  res.json({ message: `Fetching user with id: ${id}` })
})

// GET /users/42  →  { message: "Fetching user with id: 42" }
// GET /users/99  →  { message: "Fetching user with id: 99" }
```

You can also have **multiple parameters** in a single route:

```plaintext
app.get('/users/:userId/posts/:postId', (req, res) => {
  const { userId, postId } = req.params
  res.json({ userId, postId })
})

// GET /users/5/posts/12  →  { userId: "5", postId: "12" }
```

> ⚠️
> 
> **Params are always strings**Even if the value looks like a number, `req.params.userId` will be the string `"42"`, not the number `42`. Use `parseInt()` or `Number()` if you need a number for DB queries.

* * *

## 05 — Express Code - Accessing Query Strings in Express

Query strings are read from `req.query`. You don't declare them in the route — they just show up automatically when included in the URL.

```javascript
app.get('/products', (req, res) => {
  const { category, sort, limit } = req.query

  // Provide defaults in case they're missing
  const safeLimit = limit ? parseInt(limit) : 20
  const safeSort  = sort || 'asc'

  res.json({ category, sort: safeSort, limit: safeLimit })
})

// GET /products?category=shoes&sort=price&limit=5
//   → { category: "shoes", sort: "price", limit: 5 }

// GET /products
//   → { category: undefined, sort: "asc", limit: 20 }
```

You can also combine both in a single route — a URL param to identify the resource and query strings to control the response:

```javascript
app.get('/users/:userId/posts', (req, res) => {
  const { userId }       = req.params  // who
  const { sort, limit } = req.query   // how to return

  res.json({
    message: `Posts for user ${userId}`,
    sort, limit
  })
})

// GET /users/5/posts?sort=latest&limit=10
//   → { message: "Posts for user 5", sort: "latest", limit: "10" }
```

> ✅
> 
> **Always add defaults for query strings**Since query strings are optional, always handle the case where they're missing. A default sort order or page size prevents crashes and makes your API friendlier.  

* * *

## 06 — Decision Guide - When to Use Params vs Query

The rule of thumb is simple: **if you're identifying something specific, use a param. If you're filtering or modifying results, use a query string.**

![](https://cdn.hashnode.com/uploads/covers/696f9f5589255b82f81f6b17/a9f430dc-91a1-4f8e-b0b9-6b18707eace6.png align="center")

Here's a practical example that shows the difference clearly:

```plaintext
// ✅ USE PARAMS — fetching one specific user (identifier)
GET /users/42

// ✅ USE QUERY — filtering a list of users
GET /users?role=admin&active=true

// ✅ BOTH — get posts of user 42, sorted and paginated
GET /users/42/posts?sort=latest&page=2

// ❌ AVOID — filtering via params (awkward, harder to extend)
GET /users/admin/active
```

* * *

## Quick Reference - Summary at a Glance

```javascript
 ─── ROUTE WITH BOTH ───────────────────────────────────────
app.get('/users/:userId/posts', (req, res) => {

  // URL Param → identifies the user
  const userId = req.params.userId       // "42"

  // Query Strings → control the response
  const sort  = req.query.sort || 'asc'  // "latest"
  const limit = req.query.limit || 10   // "5"

  res.json({ userId, sort, limit })
})

// Request: GET /users/42/posts?sort=latest&limit=5
// Response: { userId: "42", sort: "latest", limit: "5" }
```

* * *

* * *

Params **identify**. Query strings **filter**. Use both together for clean, readable APIs.

URL Parameters vs Query Strings in Express.js

* * *
