URL Parameters vs Query Strings in Express.js
Stop confusing params and query in Express.js

Table of Contents
What are URL Parameters?
What are Query Strings?
Differences Between Them
Accessing Params in Express
Accessing Query Strings in Express
When to Use Which
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:
// :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 identifiersURL 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 &.
/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:
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 filtersQuery 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
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..
// 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:
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 stringsEven if the value looks like a number,
req.params.userIdwill be the string"42", not the number42. UseparseInt()orNumber()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.
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:
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 stringsSince 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.
Here's a practical example that shows the difference clearly:
// ✅ 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
─── 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



