How to use routers with Express and split your API logic šŸ—ƒļø

How to use routers with Express and split your API logic šŸ—ƒļø

Because the monolithic approach is lame in 2022

Is your app.js API file becoming a big pile of code nonsense? Do you have trouble distinguishing one endpoint from another? Well then, this tutorial is definitely for you!

In this article, we will take a look at how you can split your endpoints logic into different files by utilizing the express.Router class.

As always, here is the official documentation link for a more detailed look at Express routing.

The basic setup

Letā€™s suppose that our API looks like this:

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

app.get("/", (req, res) => {
  res.send('hello world');
})

app.post("/", (req,res) => {
  // User login code
  // ā€¦
})

This is the most basic setup, and itā€™s quite ok if you donā€™t plan on using too many endpoints.

But letā€™s suppose we want to add another path to our API. Our code would look like this:

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

// Home route - - - - - - -
app.get("/", (req, res) => {
  res.send('hello world');
})

app.post("/", (req,res) => {
  // User login code
  // ā€¦
})

// Register route - - - - - - - - - -
app.get("/register", (req, res) => {
  res.send('Register an account');
})

app.post("/register", (req,res) => {
  const user = req.body.username;
  const password = req.body.password; // Always encrypt passwords
})

Now it starts to get a bit difficult to read, hence the comments to section out the different routes.

A better technique

Luckily, we can create chainable route handlers for each path, and reduce some of the repetitive code.

We can do that by using the .route() built-in method. Hereā€™s how that works:

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

// Home route - - -
app.route("/")
  .get((req, res) => {
    res.send('hello world');
  })
  .post((req, res) => {
    // User login code
  })

// Register route - - -
app.route("/register")
  .get((req, res) => {
    res.send('Register an account');
  })
  .post((req, res) => {
    const user = req.body.username;
    const password = req.body.password; // Always encrypt passwords
  })

Yea, that looks much better. But still, itā€™s not practical for a large number of endpoints, since all of our code is on the same file. You can imagine how messy that can get if we just keep adding more.

The routers solution

Letā€™s take a step back and look at our projectā€™s directory tree.

At this point itā€™s very simple, just our app.js file:

/project-root-folder
  app.js

But in order to start using routers, it is best practice if we make a separate directory to store them. So letā€™s make one:

/project-root-folder
  app.js
  /routers

Great, now we can start creating our router files. Letā€™s make one for our "/" endpoint named homeRoute.js:

/project-root-folder
  app.js
  /routers
    homeRoute.js
const express = require('express');
const router = express.Router();

router.route("/")
  .get((req,res) => {
    res.send('hello world');
  })
  .post((req,res) => {
    // User login code
  })

module.exports = router;

Okay, so what is going on here?

A router file is a JavaScript module, a piece of code that can be imported when needed. More on modules here. For it to work, you need to require express and use the module.exports command at the end of the file.

Right, so how on earth do we use that in our app.js file? Hereā€™s how:

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

// Import the homeRoute.js file
const homeRoute = require('./routes/homeRoute');

// Use it as an endpoint
app.use(homeRoute);

Now thatā€™s what Iā€™m talking about!

Letā€™s implement the "/register" route in the same fashion and call it a day:

/project-root-folder
  app.js
  /routers
    homeRoute.js
    registerRoute.js
const express = require('express');
const router = express.Router();

router.route("/register")
  .get((req,res) => {
    res.send('Register an account');
  })
  .post((req,res) => {
    const user = req.body.username;
    const password = req.body.password; // Always encrypt passwords
  })

module.exports = router;

And in app.js:

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

const homeRoute = require('./routes/homeRoute');
const registerRoute = require('./routes/registerRoute');

app.use(homeRoute);
app.use(registerRoute);

Conclusions

And that was it! šŸŽ‰

I hope this helped you organize your Express API as it grows bigger with more endpoints. In a future blog post, we will explore the concept of controllers, a more advanced technique for splitting your JavaScript logic.

Till next time! āœŒļø

Ā