Structuring your Routes using Express Router

Summary: in this tutorial, you will learn how to use Express Router to modularize and organize your routing logic.

The Express router helps you organize and modularize routers in your Express application by defining routes in separate files.

Let’s take an example of using Express Router.

Creating an Express application

Step 1. Create a new project directory such as express-router-demo:

mkdir express-router-demo
cd express-router-demoCode language: JavaScript (javascript)

Step 2. Init the project by running the npm init command:

npm init -yCode language: JavaScript (javascript)

This will create package.json file in the project directory.

Step 3. Create .env file in the project directory and define the PORT constant with a value of 3000:

PORT=3000Code language: JavaScript (javascript)

Step 4. Configure the package.json file:

...
  "type": "module",
  "scripts": {
    "start": "node --env-file=.env --watch index.js"
  },
...Code language: JavaScript (javascript)

In the package.json file:

  • Add the "type": "module"entry to use ES modules.
  • Add "start": "node --env-file=.env --watch index.js" entry to the scripts section to watch the index.js file and load the .env file when the app starts.

Step 5. Install the express package:

npm install expressCode language: JavaScript (javascript)

Step 6. Create index.js file with the following code:

import express from 'express';

const app = express();
const PORT = process.env.PORT || 3000;

// Todo routes
app.get('/todos', (req, res) => {
  res.send('A list of todo items');
});

app.post('/todos', (req, res) => {
  res.send('Create a new todo item');
});

app.put('/todos/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Update the todo item with id ${id}`);
});

app.delete('/todos/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Delete the todo item with id ${id}`);
});

app.get('/todos/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Get the todo item with id ${id}`);
});

app.listen(PORT, () => {
  console.log(`The server is listening on port ${PORT}.`);
});Code language: JavaScript (javascript)

The index.js starts an express application and defines the various routes to manage the todo resource. This app works but has the following potential issues:

  • Monolithic size – The index.js becomes large when you add more code, making it difficult to navigate to different parts.
  • Maintainability – It’ll be difficult to maintain the file like adding new features without affecting other parts of the code.
  • Lack of separation of concerns – Mixing routes, middleware, and application setup in a single file violates the separate of concern principle, which makes it harder to understand different parts of the app.
  • Scalability – When the app grows, it’ll be challenging to add new routes, which leads to longer development time.
  • Testing – it’ll be difficult to test individual route groups because all of them are on the same file, making it harder to ensure that the app works properly.

Using Express Router

Step 1. Create a new directory called routes within the project directory:

cd express-router-demo
mkdir routesCode language: JavaScript (javascript)

Step 2. Define a new file called todos.js within the routes directory:

import express from 'express';
const router = express.Router();

router.get('/todos', (req, res) => {
  res.send('A list of todo items');
});

router.post('/todos', (req, res) => {
  res.send('Create a new todo item');
});

router.put('/todos/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Update the todo item with id ${id}`);
});

router.delete('/todos/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Delete the todo item with id ${id}`);
});

router.get('/todos/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Get the todo item with id ${id}`);
});

export default router;Code language: JavaScript (javascript)

How it works.

First, import the express function from the express library:

import express from 'express';Code language: JavaScript (javascript)

Second, create a new instance of the Router:

const router = express.Router();Code language: JavaScript (javascript)

This Router instance allows you to define and manage routes in a modular way.

Third, define routes for the todo resource using the Router object:

router.get('/', (req, res) => {
  res.send('A list of todo items');
});

router.post('/', (req, res) => {
  res.send('Create a new todo item');
});

router.put('/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Update the todo item with id ${id}`);
});

router.delete('/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Delete the todo item with id ${id}`);
});

router.get('/:id', (req, res) => {
  const { id } = req.params;
  res.send(`Get the todo item with id ${id}`);
});Code language: JavaScript (javascript)

In these routes, we don’t have to explicitly specify the /todos or /todos/:id but / and /:id. This feature is called route prefixing.

The route prefixing allows you to prefix routes with a common path segment. We’ll use route prefixing in the index.js file shortly.

Fourth, export the router as a default export:

export default router;Code language: JavaScript (javascript)

Step 3. Modify the index.js file as follows:

import express from 'express';
import todoRoutes from './routes/todos.js';

const app = express();
const PORT = process.env.PORT || 3000;

app.use('/todos', todoRoutes);

app.listen(PORT, () => {
  console.log(`The server is listening on port ${PORT}.`);
});Code language: JavaScript (javascript)

In the index.js file:

First, import the todoRoutes from the './routes/todos.js' module:

import todoRoutes from './routes/todos.js';Code language: JavaScript (javascript)

Since we export the router object as a default export from the /routes/todos.js module, we can use any alias when importing it.

In this example, we use the todoRoutes to make it more obvious. When the app grows, you may have more routers like userRoutes, noteRoutes, etc.

Second, mount the todoRoutes at the /todos path using the app.use() method:

app.use('/todos', todoRoutes);Code language: JavaScript (javascript)

In this example:

  • /todos is the path prefix.
  • todoRoutes is a router so that any request to /todos will be handled by corresponding route handlers defined in the todoRoutes.

The path prefixing will prefix all routes defined in the /routes/todos.js with /todos.

For example, GET /todos/ will be handled by router.get('/', ...) and GET /todos/:id will be handled by the route router.get('/todos/:id', ...).

By moving routes from the index.js to the /routes/todos.js and using Express Router makes the code more maintainable and scalable.

Download the project source code

Download the project source code

Summary

  • Use Express Router to organize routes into separate modules to achieve a more scalable and maintainable codebase.
Was this tutorial helpful ?