Introduction to Express' Router

Oct 17, 2019

Routing in Express means mapping an HTTP request to the appropriate request handler. In Express, a request handler is a callback function with the following signature:

function requestHandler(req, res) {}

For example, if you receive an HTTP GET request for /route1, Express should call the request handler for GET /route1 and not call the request handler for GET /route2. Here's how you can define a request handler for GET /route1:

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

// When `app` receives a GET request to `/route1`, Express calls
// the `requestHandler()` function.
app.get('/route1', function requestHandler(req, res) {
  res.send('Hello from route1');

// Listen for requests on port 3000

Testing with Axios

The easiest way to see your Express app in action is using Axios - no need to remember CURL flags. Here's a simple script that starts an Express server and makes an HTTP request to that server using Axios and async/await.

const app = require('express')();
app.get('/route1', (req, res) => res.send('Hello, World!'));
// `app.listen()` returns a promise. Once this promise
// resolves, that means Express is ready to handle requests.
const server = await app.listen(3000);

const axios = require('axios');
const res = await axios.get('http://localhost:3000/route1');; // 'Hello, World!'

Other HTTP Request Methods

The app.get() function defines a request handler specifically for an HTTP GET request. However, there are several HTTP request methods in addition to GET:

Express has a separate function for each of these request methods:

Most apps just use app.get(),, app.put(), and app.delete(). However, app.options() is useful for CORS. Here's how you can define a POST handler:'/route1', function(req, res) {
  res.send('Hello from POST /route1');

The app.all() function lets you define a route handler for all HTTP methods:

// Express will call `routeHandler()` for any request to
// `/route1`, regardless of the request method. For example,
// `GET /route1` and `POST /route1` both trigger `routeHandler`.
app.all('/route1', function routeHandler(req, res) {});

Wildcards and Route Parameters

Express routing supports a subset of regular expressions, including wildcards. For example, the below is how you define a request handler for all URIs:

// Express will call `requestHandler()` for **every** GET request.
app.get('*', function requestHandler(req, res) {});

The : character is how you define a route parameter in Express. A route parameter is a named section of the URL - Express captures the value in the named section and stores it in the req.params property.

// Express stores whatever string comes after `/user/` in
// ``
app.get('/user/:id', (req, res) => res.json({ id: }));

await app.listen(3000);

let res = await axios.get('http://localhost:3000/user/test1');; // 'test1'

res = await axios.get('http://localhost:3000/user/test2');; // 'test2'

You can also define multiple route parameters. Route parameters are delimited by /.

// `GET /flight/MIA/JFK` means `req.params` is equal to
// `{ from: 'MIA', to: 'JFK' }`
app.get('/flight/:from/:to', (req, res) => res.json(req.params));


The express.Router() function creates a subrouter. A subrouter is an Express middleware that behaves like a mini Express app. It has the same get(), post(), all(), etc. methods that an Express app does for defining route handlers.

Routers are commonly used as Express sub-apps. For example, you may have a separate router for REST API requests and another router for custom views.

// Set up an API sub-app...
const api = express.Router();

api.get('/users', (req, res) => { res.json({ users: [] }); });

// And a views sub-app...
const views = express.Router();
const fs = require('fs');
const usersPage = fs.readFileSync('./views/users.html', 'utf8');

views.get('/users', (req, res) => res.send(usersPage));

// And add them to a top-level app
const app = express();

// Handles `GET /api/users`
app.use('/api', api);
// Handles `GET /views/users`
app.use('/views', views);

Want to become your team's Express expert? There's no better way to really grok a framework than to write your own clone from scratch. In 15 concise pages, this tutorial walks you through how to write a simplified clone of Express called Espresso. Get your copy!

Espresso supports:
  • Route handlers, like `app.get()` and ``
  • Express-compatible middleware, like `app.use(require('cors')())`
  • Express 4.0 style subrouters
As a bonus, Espresso also supports async functions, unlike Express.

Get the tutorial and master Express today!

More Express Tutorials