Routing in Express Js

Abhishek JhaAbhishek Jha
7 min read

In this article, we will learn about routing in Express Js that we will use whether we are developing REST API or full-stack applications. Let's understand, why we need routing and how it will help us to manage application code better and also help in implementing coding principles like DRY and SOLID.

What is Routing?

We access anything in any application using some endpoints(URL) and whenever we make any request some code on the server executes to complete our request and give us the response. If we divide it into parts we have two things one is the endpoint and the second is the code that executes on the server, this is where routing helps us to map our endpoints with the specific piece of functionality from our application.

Why do we need Routing?

Here's why routing is necessary.

  1. URL Mapping

    Routing allows you to map URLs to specific functions or handlers within your application.

  2. Separation of Concerns

    It helps to separate different parts of the application from one another like authentication, authorization, admin, and users.

  3. Dynamic URL Handling

    A route /users/:id can dynamically match any user ID and allow your application to fetch or process data for that specific user.

  4. Implementing RESTful APIs

In RESTful API design, routing is responsible for mapping HTTP methods (GET, POST, PUT, PATCH, DELETE) to actions on resources.

  1. Middleware Integration

    It is a function that runs before the final request handler to process or modify the request or response in an application.

  2. Error Handling

    With routing, you can define specific routes to handle errors or exceptions. For instance, you can create a catch-all route for 404 errors to handle cases where users navigate to a non-existent page.

  3. Modular Code Structure

    Routing allows you to break your application into smaller, more manageable modules or files.

HTTP Methods

There are several HTTP methods, but the most commonly used ones are:

  1. GET To retrieve resources from the server

  2. POST Submit to create new resources on the server like registering a new user.

  3. PUT To replace any resource from the server like replacing any image with a new

  4. PATCH: To update resources on the server like updating a user's email address.

  5. DELETE To delete resources from the server.

How to declare routes

/** Importing the express Js */
const express = require("express");

/** Creating a new instance of router. */
const router = express.Router();
/**
 * The first is method which we will choose according to our need.
 * The first parameter is the url we want to assign that functionality.
 * Second parameter is a callback function that will be executed when user hit that URL
 * Callback function will have two parameter that is request,response.
 */

router.get("/url", (req, res) => {});

As of now, we have gained a rough idea of routing and the purpose with methods, now we will see how Express Js helps with Routing. Express Js has a built-in routing mechanism we can access using the code below.

/** Importing the express Js */
const express = require("express");

/** Creating a new instance of router. */
const router = express.Router();

/**
 * GET
 * URI /list-of-tasks
 * To get the list of tasks to do
 */
router.get("/list-of-tasks", (req, res) => {
  const tasks = [
    { id: 1, name: "Task 1", description: "This is the first task" },
    { id: 2, name: "Task 2", description: "This is the second task" },
    { id: 3, name: "Task 3", description: "This is the third task" },
  ];
  res.json(tasks);
});
/** Exporting routes to register in the app to make it available to accept request and return response */
module.exports = router;

We will see how and when to use different HTTP methods for that we will do a basic CRUD and to get the request we will install a new package to parse the request body. Please run the command to install the package npm install body-parser after that create a file routes.js in the project folder(express-01) and paste the below code in main.js file that we have created in the last article.

NOTE: Don't worry about the HTML we will see in the upcoming article for handling views.

/**Importing the express Js */
const express = require('express');

/** Initializing the express application */
const app = express();
const bodyParser = require('body-parser');

app.use(bodyParser.urlencoded({ extended: true }));

/** Register the route to accept the get request */
app.get('/',(req,res,next) => {
    res.send('Hello World');
});

const customRoutes = require('./routes');

app.use(customRoutes);

/** Create server and start listing on the port of your choice */
app.listen(3000);

Paste the below code into the routes.js file

/** Importing the express Js */
const express = require("express");

/** Creating a new instance of router. */
const router = express.Router();

const tasks = [
    { id: 1, name: "Task 1", description: "This is the first task" },
    { id: 2, name: "Task 2", description: "This is the second task" },
    { id: 3, name: "Task 3", description: "This is the third task" },
];

/**
 * GET
 * URI /list-of-tasks
 * To get the list of tasks to do
 */
router.get("/list-of-tasks", (req, res) => {
    res.send(
        `<body style="font-family: Arial, sans-serif; margin: 20px;">

            <h1 style="text-align: center;">Task List</h1>
            <div style="text-align: center; margin-bottom: 20px;">
                <a href="/add-task" style="display: inline-block; background-color: #007BFF; color: white; text-align: center; border: none; border-radius: 5px; padding: 10px 20px; cursor: pointer; text-decoration: none; font-size: 16px; margin-bottom: 20px;">
                    Add New Task
                </a>
            </div>

            <ul style="list-style-type: none; padding: 0; max-width: 600px; margin: 0 auto;">`
                + tasks.map((task) => {
                    return  `<li style="border: 1px solid #ddd; border-radius: 5px; padding: 10px; margin-bottom: 10px; display: flex; justify-content: space-between; align-items: center;">
                    <div style="flex: 1;">
                        <h2 style="margin: 0; font-size: 18px; color: #333;">${task.name}</h2>
                        <p style="margin: 5px 0 0; color: #666;">${task.description}</p>
                    </div>
                    <a href="/edit-task/${task.id}" style="display: inline-block; background-color: #4CAF50; color: white; text-align: center; border: none; border-radius: 5px; padding: 8px 16px; cursor: pointer; text-decoration: none;">
                        Edit
                    </a>
                    <form action="/delete-task/${task.id}" method="POST" style="margin-bottom:0;">
                        <button type="submit" style="display: inline-block; background-color: #9e0132; color: white; text-align: center; border: none; border-radius: 5px; padding: 8px 16px; cursor: pointer;  margin-left:10px;">Delete</button>
                    </form>

                </li>`;
                }).join("")+`
            </ul>

        </body>`
    );  
});

/**
 * GET
 * URI /add-task
 * To get the list of tasks to do
 */
router.get("/add-task", (req, res) => {
    res.send(` <body style="display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0;">
    <div style="text-align: center;">
        <h1>Add New Task</h1>

        <form action="/submit-task" method="post" style="display: inline-block; text-align: left;">
            <div style="margin-bottom: 15px;">
                <label for="name" style="display: block; margin-bottom: 5px;">Name:</label>
                <input type="text" id="name" name="name" required style="width: 100%; padding: 8px; box-sizing: border-box;">
            </div>
            <div style="margin-bottom: 15px;">
                <label for="description" style="display: block; margin-bottom: 5px;">Description:</label>
                <textarea id="description" name="description" rows="4" cols="50" required style="width: 100%; padding: 8px; box-sizing: border-box;"></textarea>
            </div>
            <button type="submit" style="padding: 10px 20px; font-size: 16px;">Submit</button>
        </form>
    </div>
</body>`);
res.end();
});

/**
 * POST
 * URI /add-tasks
 * To add new task.
 */
router.post('/submit-task',(req,res) => {
    const newTask = {
        id: tasks.length + 1,
        name: req.body.name,
        description: req.body.description,
    }
    tasks.push(newTask);
    res.redirect('/list-of-tasks');

});

/**
 * GET 
 * URI /edit-task/:id
 * To get an edit form to update the task
 */
router.get("/edit-task/:id", (req, res) => {
    const taskId = req.params.id;
    const task = tasks.find((task) => task.id === parseInt(taskId));
    if (!task) {
        res.status(404).send("Task not found");
        return;
    }

    res.send(` <body style="display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0;">
    <div style="text-align: center;">
        <h1>Update Task</h1>

        <form action="/update-task/${task.id}" method="post" style="display: inline-block; text-align: left;">
            <div style="margin-bottom: 15px;">
                <label for="name" style="display: block; margin-bottom: 5px;">Name:</label>
                <input type="text" id="name" name="name" required style="width: 100%; padding: 8px; box-sizing: border-box;" value="${task.name}">
            </div>
            <div style="margin-bottom: 15px;">
                <label for="description" style="display: block; margin-bottom: 5px;">Description:</label>
                <textarea id="description" name="description" rows="4" cols="50" required style="width: 100%; padding: 8px; box-sizing: border-box;" value="${task.description}">${task.description}</textarea>
            </div>
            <button type="submit" style="padding: 10px 20px; font-size: 16px;">Submit</button>
        </form>
    </div>
</body>`);
});

/**
 * POST
 * URI /update-task/:id
 * To update task based on id
 */
router.post("/update-task/:id",(req,res) => {
    const taskId = req.params.id;
    const task = tasks.find((task) => task.id === parseInt(taskId));
    if (!task) {
        res.status(404).send("Task not found");
        return;
    }
    const newTask = {
        id: task.id,
        name: req.body.name,
        description: req.body.description
    }
    Object.assign(task, newTask);
    res.redirect('/list-of-tasks');
});

/**
 * POST
 * URI delete-task/:id
 * To delete the task based on id
 */
router.post('/delete-task/:id',(req,res) => {
    const taskId = req.params.id;
    const task = tasks.find((task) => task.id === parseInt(taskId));

    if (!task) {
        res.status(404).send("Task not found");
        return;
    }
    const index = tasks.indexOf(task);
    tasks.splice(index, 1);
    res.redirect('/list-of-tasks');
})
/** Exporting routes to register in the app to make it available to accept request and return response */
module.exports = router;

Conclusion

In conclusion, routing in Express.js is a fundamental aspect of building robust and organized web applications, whether you're developing REST APIs or full-stack solutions. By mapping URLs to specific functions or handlers, routing enables us to effectively manage and structure our application code.

We've explored the various components of routing, including URL mapping, dynamic URL handling, middleware integration, and error handling, each contributing to a cleaner and more maintainable codebase. With Express.js's built-in routing capabilities, we can efficiently handle different HTTP methods and modularize our application into manageable routes.

2
Subscribe to my newsletter

Read articles from Abhishek Jha directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abhishek Jha
Abhishek Jha

Behold, the coding maestro! ๐ŸŽฉ Armed with PHP, Laravel, Linux, HTML, JavaScript, Jquery & Vue, I conquer both frontend and backend realms. ๐Ÿš€ Pressure? No match for me. I deliver excellence and exceed expectations with flair. ๐ŸŒŸ Stay ahead, stay cool, and let's conquer the coding universe together! ๐Ÿ’ป