Node.js

How to capture incoming HTTP request parameters.

An incoming request carries data in three places: the query string, the route path, and the body. Here’s how to read each in Node.js and Express — req.query, req.params, req.body — including how they’re decoded and how to handle webhook payloads safely.

The three places parameters live

SourceExampleExpress
Query string?q=hello&page=2req.query
Route params/users/:idreq.params
Request bodyPOST JSON / formreq.body

Query parameters

In Express, req.query is already parsed and decoded:

app.get('/search', (req, res) => {
  req.query.q;      // "hello"  (decoded)
  req.query.page;   // "2"
  res.json(req.query);
});

In a raw Node server there’s no req.query — parse it yourself with the URL class:

const http = require('node:http');
http.createServer((req, res) => {
  const url = new URL(req.url, `http://${req.headers.host}`);
  const q = url.searchParams.get('q');           // one value
  const all = Object.fromEntries(url.searchParams); // object
  res.end(JSON.stringify(all));
}).listen(3000);

Route parameters

Named segments in the route become req.params. Express decodes them for you:

app.get('/users/:id/posts/:postId', (req, res) => {
  req.params.id;      // "42"
  req.params.postId;  // "7"
});

Body parameters (POST)

The body isn’t parsed unless you add middleware. For JSON and form bodies:

app.use(express.json());                          // application/json
app.use(express.urlencoded({ extended: true }));  // x-www-form-urlencoded

app.post('/submit', (req, res) => {
  req.body.username;   // from JSON or form body
});

Repeated query keys

By default Express turns ?tag=a&tag=b into an array: req.query.tag === ["a","b"]. If a client sends a single value, it’s a string — so normalize before you rely on it:

const tags = [].concat(req.query.tag || []);  // always an array

Webhooks: validate before you trust

Incoming webhook parameters are attacker-controllable. Never interpolate them into a shell command, SQL query, or file path unescaped, and verify any signature the sender provides before acting. Our decode-then-validate guide covers hardening request input.

To see how a request’s query string breaks down, paste it into the query string parser.

About this page

Written and maintained by the urlencodedecode.com team. Every technical claim on this page is verified against primary sources — the RFCs (3986, 3629, 4648, 7578), the WHATWG URL Standard, and official vendor or language documentation — rather than second-hand summaries. When a source contradicts a common assumption, we follow the source and note the discrepancy. Corrections: contactus@urlencodedecode.com.

Common questions

Frequently asked.

In Express, use req.query — it's already parsed and decoded, so req.query.q returns the value of ?q=. In a raw http server, parse req.url with the URL class and read url.searchParams.get(key).

req.query holds the query-string parameters (?q=hello), req.params holds named route segments (/users/:id), and req.body holds the POST body (JSON or form data, once you add express.json or express.urlencoded middleware).

Express doesn't parse the request body by default. Add express.json() for JSON bodies and express.urlencoded({ extended: true }) for form-encoded bodies before your routes, and req.body will be populated.

Express parses repeated keys into an array, so req.query.tag becomes ["a","b"]. A single occurrence stays a string, so normalize with [].concat(req.query.tag || []) when you need to always treat it as an array.

Yes. Express's req.query and the URL class's searchParams both percent-decode values for you, and treat + as a space in the query string. You don't need to call decodeURIComponent yourself.

Related

Keep exploring.