Node express router

How do we use an express router and create a modular structure to scale our application.

Node express router

It's important that we start by understanding the flow of a request in a node.js server. Take a moment to observe the diagram below. (this diagram does not contain the middleware and it will be covert in another article.)

The examples below will use TypeScript and the only difference if you use JavaScript, is to make sure the you use require instead of import and to export you should use module.exports

Express server HTTP request flow

In this example we see that a get request is sent  to a route /api/users on our express web server. If we did not declare such a route, the express server will respond with a status code of 404 and display an HTML with Cannot get /api/users.

Let's start building our express web server and define these route.

Start by creating your project folder and then run yarn init or npm init.

if you don't have nodemon, please install it for your developer experience npm i -g nodemon.

Install express npm i express -S or yarn add express.

create your src/index.js file and write your express server like this.

// src/index.ts
import express from 'express'

const PORT = process.env.PORT || 4000
const app = express()

app.get('api/users',(req,res)=> {
	res.send("Users!")
})

app.listen(PORT,()=> console.log(`Listening on port ${PORT}`))

Now lets run our code with nodemon nodemon src/index.js

Ok, now let's overview what we wrote.  If you are not familiar with express then let starts by having a look at our express app initialisation const app = express() this gives us the instance of express app that we are going to work with.  You can see that we have app.get this means that we declare a route with the GET http method and the first parameter is the path  /users. the second parameter is a callback that is executed when someone makes a request to this route.

the callback contains 2 parameters

  1. request object that contains all the information about the request.
  2. response object that allows us to respond to the request.

Once the callback is called we respond with a string "Users!" and you can test that by going to http://localhost:4000/api/users.

You can define multiple routes and different method and that's what you basically do in a typical express server.

You can guess that if we define more than 1 route in that src/index.js , it will become messy pretty quickly. That's where express router comes to the rescue.

A router object is an isolated instance of middleware and routes. You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router.

Let's start by giving a proper structure to our app by defining folder hierarchy .

Scaleable folder structure

Let's create our modular route src/components/user/index.js.

Inside our index.js we will define our modular route for all endpoints related to /users.

// src/components/user/index.ts
import {Router} from 'express'

const router = Router();

router.get('/',(_req,res)=>{
    const user = {
        firstName:'John',
        lastName:'Daw'
    }

    res.send(user)
})

export const userRouter = router;

We start by importing Router from express library and then declaring our router.

Next is similar to what we did on our root index.js we defined a get method but the endpoint is just a /. Worry not as this will become our api/users endpoint.

We finish our modular user router by exporting it.

Next we want to use what we declared in our src/components/user/index.js to be used as our routing for all /user paths and to do that we are going to define an index.js file inside our src/components folder.

This index.js file, will take care of all our modular routers and assign them to their rightful path!.

// src/components/index.ts
import {Router} from 'express'
import { userRouter } from './user';

const router = Router();

router.use('/user',userRouter)

export const apiRouter = router;

Once again we import the Router from express and define our router. We then use the router.use method that allows us to use the router we defined for our user path handling as a middleware and in simple words it means, please use this router to all endpoint starting with /user/.

then we export our newly defined router as an apiRouter and move to our root index.js

// src/index.ts
import express from 'express'
import { apiRouter } from './components'

const PORT = process.env.PORT || 4000
const app = express()

app.use('/api',apiRouter)

app.listen(PORT,()=> console.log(`Listening on port ${PORT}`))
Express web server definition

We will now import our apiRouter and use it to handle all our /api routes.

That's how simple it is to separate our logic from our express server definition with express router.