← Back to all tutorials

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 CaseTypeExample
Identifying a resourceRoute parameter/api/ninjas/:id
Filtering resultsQuery string/api/ninjas?rank=5
Sorting resultsQuery string/api/ninjas?sort=name
PaginationQuery 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

ScenarioStatus CodeExample
Successful GET200res.status(200).json(data)
Resource created201res.status(201).json(newItem)
Deleted successfully204res.status(204).send()
Bad request body400res.status(400).json({error})
Resource not found404res.status(404).json({error})
Server error500res.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 via req.params
  • Query strings (?key=value) are used for filtering, sorting, and pagination — accessed via req.query
  • Define specific routes before parameterized routes to avoid accidental matches
  • Always send appropriate HTTP status codes with your responses