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-demo
Code language: JavaScript (javascript)
Step 2. Init the project by running the npm init
command:
npm init -y
Code 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=3000
Code 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 thescripts
section to watch theindex.js
file and load the.env
file when the app starts.
Step 5. Install the express
package:
npm install express
Code 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 routes
Code 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 thetodoRoutes
.
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.