Handling Requests
Learn how Express processes incoming requests — the request-response cycle, route matching, and working with URL parameters and query strings.
Handling Requests
Now that your Express server is running, let us dive deeper into how Express matches and handles requests. You will learn about route parameters, query strings, the request-response cycle, and how Express processes incoming requests.
The Request-Response Cycle
Client sends request
↓
Express receives it
↓
Middleware runs (if any)
↓
Express matches the URL and method to a route
↓
Route handler executes
↓
Response is sent back to the client
Every request goes through this cycle. Express checks each route in order and runs the first one that matches both the URL path and the HTTP method.
Route Parameters
Route parameters are named segments in the URL that capture dynamic values:
// :id is a route parameter
app.get('/api/ninjas/:id', (req, res) => {
const ninjaId = req.params.id;
res.json({ id: ninjaId, message: `Details for ninja ${ninjaId}` });
});
// Multiple parameters
app.get('/api/ninjas/:ninjaId/weapons/:weaponId', (req, res) => {
res.json({
ninja: req.params.ninjaId,
weapon: req.params.weaponId,
});
});
// GET /api/ninjas/42/weapons/7
// req.params → { ninjaId: '42', weaponId: '7' }
Parameters are always strings. If you need a number, convert it: Number(req.params.id) or parseInt(req.params.id).
Query Strings
// GET /api/ninjas?rank=5&sort=name
app.get('/api/ninjas', (req, res) => {
console.log(req.query);
// { rank: '5', sort: 'name' }
res.json({
rank: req.query.rank,
sort: req.query.sort,
});
});
Query strings come after the ? in the URL. They are used for filtering, sorting, and pagination — things that do not identify a resource but modify the result.
When to Use Params vs Query
| Use Case | Type | Example |
|---|---|---|
| Identifying a resource | Route parameter | /api/ninjas/:id |
| Filtering results | Query string | /api/ninjas?rank=5 |
| Sorting results | Query string | /api/ninjas?sort=name |
| Pagination | Query string | /api/ninjas?page=2&limit=10 |
Sending Different Response Types
// JSON response (most common for APIs)
app.get('/api/data', (req, res) => {
res.json({ key: 'value' });
});
// String response
app.get('/text', (req, res) => {
res.send('Plain text response');
});
// Status code with response
app.get('/api/notfound', (req, res) => {
res.status(404).json({ error: 'Resource not found' });
});
// No content response
app.delete('/api/ninjas/:id', (req, res) => {
res.status(204).send();
});
Route Order Matters
// This works correctly
app.get('/api/ninjas/special', (req, res) => {
res.json({ message: 'Special ninja route' });
});
app.get('/api/ninjas/:id', (req, res) => {
res.json({ message: 'Ninja ' + req.params.id });
});
// If reversed, /api/ninjas/special would match :id = 'special'!
Express matches routes in the order they are defined. Specific routes should come before parameter-based routes, otherwise the parameter will capture the specific path segment.
Sending Status Codes
| Scenario | Status Code | Example |
|---|---|---|
| Successful GET | 200 | res.status(200).json(data) |
| Resource created | 201 | res.status(201).json(newItem) |
| Deleted successfully | 204 | res.status(204).send() |
| Bad request body | 400 | res.status(400).json({error}) |
| Resource not found | 404 | res.status(404).json({error}) |
| Server error | 500 | res.status(500).json({error}) |
Key Takeaways
- Express matches routes by URL path and HTTP method in the order they are defined
- Route parameters (
:id) capture dynamic URL segments — accessed viareq.params - Query strings (
?key=value) are used for filtering, sorting, and pagination — accessed viareq.query - Define specific routes before parameterized routes to avoid accidental matches
- Always send appropriate HTTP status codes with your responses