What Is express.Router() For

Express Routers are a way to organize your Express application such that your primary app.js file does not become bloated and difficult to reason about. As you’re building an Express application or API, you’ll soon notice that the routes continue to pile up in app.js. This makes the file quite long and hard to read. As we add functionality to an application, this file would get long and cumbersome. The solution to this in Express is Routers. Routers are like mini versions of Express applications. They provide functionality for handling route matching, requests, and sending responses, but they do not start a separate server or listen on their own ports. Routers use all the .get(), .put(), .post(), and .delete() routes that you are now familiar with.


Express.Router

To create an instance of an Express Router, we call the .Router() method on the top-level Express import. Then to use that router, we mount it at a certain path using app.use() and pass in the router as the second argument. This router will now be used for all paths that begin with that path segment. To create a router to handle all requests beginning with /hello, the code would look like this:

const helloRouter = express.Router();
 
app.use('/hello', helloRouter);

One Router Per File

Generally, a router will live in its own file, and then it is required into the main application. This helps to keep our code clean and our files short.

To do this with helloRouter, we would create a new file hello.js and move all code related to /hello requests into it.

This file will now contain all the /hello specific code. To use this router in another file, there needs to be a module.exports so that other files can access helloRouter.

hello.js

const express = require('express');

names = {1: 'John', 2: 'Jane', 3: 'Jack'};

helloRouter = express.Router();

// Get all names
helloRouter.get('/', (req, res) => {
    res.json(names);
    console.log(names)
});

// Get a single name
helloRouter.get('/:id', (req, res) => {
    res.json(names[req.params.id]);
    console.log(names[req.params.id])
});

// Update a single name
helloRouter.put('/:id', (req, res, next) => {
    names[req.params.id] = req.body.name;
    res.json(names[req.params.id]);
    console.log(names);
});

// Add a new name
helloRouter.post('/', (req, res) => {
    names[req.body.id] = req.body.name;
    res.json(names[req.body.id]);
    console.log(names);
});

// Delete a name
helloRouter.delete('/:id', (req, res) => {
    delete names[req.params.id];
    res.json(names);
    console.log(names);
});

module.exports = helloRouter;

Our app.js file could then be refactored to import the helloRouter:

app.js

const express = require('express');
const app = express();
app.use(express.json())
const PORT = process.env.PORT || 4001;

const helloRouter = require('./hello.js');
app.use('/hello', helloRouter);

app.listen(PORT, () => {
    console.log(`Server is listening on ${PORT}`);
});

What is pretty interesting is that just this small amount of code in the app.js file now supports a full CRUD API.


Testing The API

We can test all API endpoints in one go with this test.http file in our Jetbrains WebStorm IDE.

test.http

### get all names
GET http://localhost:4001/hello/

### update name at id 1
PUT http://localhost:4001/hello/1
Content-Type: application/json

{
  "name": "Steph"
}

### add a new name at id 4
POST http://localhost:4001/hello/
Content-Type: application/json

{
  "id": 4,
  "name": "Wilson"
}

### delete name at id 1
DELETE http://localhost:4001/hello/1

Running the tests against the API shows all endpoints working well.

What Is express.Router() For Summary

In this tutorial, we saw how to create a much more readable and clean code base using Express.Router(). Writing clean and readable code is one of the most important skills you can build. By using Express Routers, you will make adding new features much easier as your APIs grow.