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

Search for a command to run...
Stop confusing params and query in Express.js

In Express.js, URL Parameters (e.g., /user/:id) are used to identify specific resources and are accessed via req.params, while Query Strings (e.g., ?search=true) are used for filtering or sorting and are accessed via req.query. Simply put: parameters define what the resource is, while query strings define how it should be displayed.
Node.js doesn't use multiple threads to handle concurrency — and that's not a weakness. Here's exactly how it pulls off handling thousands of connections without breaking a sweat.

Table of Contents What is cURL — in very simple terms Why programmers need cURL Making your first request Understanding request and response Using cURL to talk to APIs Common mistakes beginners

A practical guide to where files live, how to expose them over HTTP, and the security rules you cannot skip.

Understanding authentication approaches · stateful vs stateless · when to use each

XP-VISHAL-WEB-DEV-COHORT-2026-BLOGS
24 posts
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
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.
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.
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.
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.
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
─── 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