Routing in Express.js explained
Tags: express, node, javascript
Published: 2021-11-30 10:06:26

---
title: Routing in Express.js explained
published: true
date: 2021-11-25 00:00:00 UTC
tags: express,node,javascript
canonical_url: https://www.mariokandut.com/routing-in-express-js-explained-node-js/
---

Express reduces complexity and makes developing and maintaining applications much easier than the built-in Node.js tools. Routing is one of three big concepts in the Express framework. Read more about Express.js in the [Introduction to Express.js](https://www.mariokandut.com/what-is-the-express-node-js-framework/).

This article is part of a large series about **Express.js**. You can find all articles here - **[Express Framework](https://www.mariokandut.com/tags/express)**.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#routing-in-express)Routing in Express

Routing refers to how an application responds to a client request to a particular endpoint, which is a URI (or a path) and a specific HTTP request method (GET, POST, etc.). Each route can have one or more handler functions, which are executed when the route is matched.

A Route definition takes the following structure: `app.METHOD(PATH, HANDLER)`

- `app` is an instance of express.
- `METHOD` is an HTTP request method, in lowercase.
- `PATH` is a path on the server.
- `HANDLER` is the function executed when the route is matched.

Let's look at an example of a route `/home` that is defined for a GET request.

```
const express = require('express');
const app = express();

// GET method route
app.get('/home', (req, res) => {
  res.send('OK');
});
```

In the above example:

- `app` is an instance of Express
- `app.get` is the HTTP request method
- `/home` is the route
- `(req, res) => {}` is the handler function, which runs in response to a matching request.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#route-methods)Route methods

A route method is derived from one of the HTTP methods, and is attached to an instance of the express class. There is a method for every HTTP verb, most commonly used below. For a full list see [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods).

- GET `.get()`
- POST `.post()`
- PUT `.put()`
- DELETE `.delete()`
- PATCH `.patch()`

#### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#route-method-all)Route method .all()

There is a special routing method `app.all()`. It is used to load middleware functions at a path for all HTTP requests.

```
app.all('/secret', (req, res, next) => {
  console.log('Accessing the secret section ...');
  next(); // pass control to the next handler
});
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#route-paths)Route paths

Route paths with a request method define the endpoints at which requests can be made. They can be **string, string patterns or regular expressions**. Query strings are not part of the route path.

The characters **?, +, \*, and ()** are subsets of their regular expression counterparts. The **hyphen (-)**, and the **dot (.)** are interpreted literally by string-based paths.

**Express uses [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) for matching the route paths**, there are many possibilities, but also limitations in choosing routes. For a full list refer to the documentation of path-to-regexp.

Here are a few examples for routes:

This route path will match requests made to `/`.

```
app.get('/', (req, res) => {
  res.send('root');
});
```

This route path will match requests made to `/home`.

```
app.get('/home', (req, res) => {
  res.send('home');
});
```

This route path will match requests made to `/info.text`.

```
app.get('/info.text', (req, res) => {
  res.send('info.text');
});
```

This route path will match requests made to `/acd` and `/abcd`.

```
app.get('/ab?cd', (req, res) => {
  res.send('ab?cd');
});
```

This route path will match requests made to `abcd`, `abbcd`, `abbbcd`, etc.

```
app.get('/ab+cd', (req, res) => {
  res.send('ab+cd');
});
```

This route path will match requests made to `abcd`, `abxcd`, `abANYRANDOMSTRINGcd`, etc.

```
app.get('/ab*cd', (req, res) => {
  res.send('ab*cd');
});
```

Since regular expressions are possible as route paths., this route path will match requests containing an `a` anywhere.

```
app.get('/a/', (req, res) => {
  res.send('/a/');
});
```

Express 4.x treats the `*` differently, see [here](https://github.com/expressjs/express/issues/2495). This behaviour is fixed since Express 5.x.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#route-parameters)Route parameters

A Route can accept dynamic values within a path, so called **route parameters**. **Route parameters are named URL segments** that are used to capture the values specified at their position in the URL. The captured values are populated in the `req.params` object, with the name of the route parameter as their key.

For example a route path `/users/:userId/books/:bookId` would require a request URL to be something like `http://localhost:3000/users/34/books/8989`, and the captured route parameters would be populated in `req.params` like this `{ "userId": "34", "bookId": "8989" }`.

To define a route parameter just specify the route parameters in the path.

```
app.get(`/users/:userId/books/:bookId`, (req, res) => {
  console.log(req.params);
});
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#route-handlers)Route handlers

Route handlers are callback functions or arrays of functions, which basically handle requests. Multiple callback functions can be provided to handle a request and behave like a middleware. The only exception is that these callbacks can call `next()` to bypass the next and remaining route callbacks. Route handlers can be in the form of a function, an array of functions, or a combination of both.

The request and response are often shortened to `req` and `res`, and stand for the request which was received by the server, and the response which will eventually be send back.

These are based on built-in objects in Node.js, the [ClientRequest](https://nodejs.org/api/http.html#http_class_http_clientrequest) and [ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse). There will be a dedicated Express routing blog post in the future.

A single HTTP transaction can be roughly described by the Request and Response cycle.

- A client sends a request to the server.
- The server receives the request, reads the data (request headers, URL path, HTTP method, query parameters, cookies, data or payload, etc.).
- The server sends a response back to the client. It includes status code, headers, content-encoding, any data being returned.
- Once the response has been sent back, the HTTP transaction is completed.

Augmenting the `req` and `res` objects is a big part of how Express enhances functionality, while still maintaining control over how requests and responses are handled.

A single callback function can handle a route like this:

```
app.get('/home', (req, res) => {
  res.send('home');
});
```

Below an array of functions example:

```
const cb0 = function(req, res, next) {
  console.log('CB0');
  next();
};

const cb1 = function(req, res, next) {
  console.log('CB1');
  next();
};

app.get('/c', [cb0, cb1]);
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#response-methods)Response methods

The methods on the response object (res) in the following table can send a response to the client, and terminate the request-response cycle. If none of these methods are called from a route handler, the client request will be left hanging.

- `res.download()` Prompt a file to be downloaded.
- `res.end()` End the response process.
- `res.json()` Send a JSON response.
- `res.jsonp()` Send a JSON response with JSONP support.
- `res.redirect()` Redirect a request.
- `res.render()` Render a view template.
- `res.send()` Send a response of various types.
- `res.sendFile()` Send a file as an octet stream.
- `res.sendStatus()` Set the response status code and send its string representation as the response body.

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#chainable-routes-with-approute)Chainable Routes with `app.route()`

With `app.route()` you can chain route handlers for a route path. Creating modular routes is helpful, because it is reducing redundancy and typos.

Let's have a look at an example of chained route handlers:

```
app
  .route('/book')
  .get(function(req, res) {
    res.send('Get a random book');
  })
  .post(function(req, res) {
    res.send('Add a book');
  })
  .put(function(req, res) {
    res.send('Update the book');
  });
```

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#tldr)TL;DR

- Route paths, in combination with a request method, define the endpoints at which requests can be made. A Route definition takes the following structure: `app.METHOD(PATH, HANDLER)`
- Route handlers are callback functions or arrays of functions.
- For every HTTP verb there is a route method.
- The special routing method `app.all()` is used to load middleware functions at a path for all HTTP requests.
- Route paths can be strings, string patterns or REGEXP.
- Routes can be chained with `app.route()`

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**.

If you want to know more about **[Express](https://www.mariokandut.com/tags/express)**, have a look at these [Express Tutorials](https://www.mariokandut.com/tags/Express).

**References (and Big thanks):**

[HeyNode](https://heynode.com/tutorial/how-add-route-express-server-nodejs),[ExpressJS](https://expressjs.com/),[Express - Routing](https://expressjs.com/en/guide/routing.html),[Express - Basic Routing](https://expressjs.com/en/starter/basic-routing.html),[path-to-regexp](https://www.npmjs.com/package/path-to-regexp)