×
Radha Kavade
Senior Software Engineer
Radha Kavade is a seasoned Senior Software Engineer at Nitor Infotech. She is an Angular expert who prioritizes code reusability and optimizes ... Read More

In the vast landscape of web development, Node.js stands tall as a powerful and event-driven server, efficiently managing server connections with its single-threaded prowess. It navigates the complexities of seamlessly processing each request within the callback, ensuring a smooth and responsive server.

Explore the nuances of Node.js and compare it with Java & .NET.

Yet, as any developer knows, handling a myriad of requests in a busy application can present challenges. That is, despite its skills, Node.js may face challenges in efficiently managing all these requests.

To tackle this problem, comes Express.js — a silent hero among web application frameworks for Node.js. It’s not just a solution; Express.js is a powerful toolkit that elevates the development process.

So, whether you’re a seasoned developer or new to web development, this blog guides you through Express.js, covering installation, building robust servers, mastering routing, grasping middleware, and more.

Let ‘s get started!

What is Express.js and why is it preferred?

Express.js is a robust web application framework for Node.js, offering extensive features for building web and mobile applications. Serving as a layer on top of Node.js, it facilitates the management of servers and routes. It is loved for being speedy, flexible, and minimalist, giving developers the freedom and control they crave over their apps.

It is popular because of these reasons:

  • Supports Model-View-Controller (MVC) architecture for versatile web app design.
  • Leverages Node.js’ single-threaded and asynchronous model for efficiency.
  • Cross-platform compatibility.

Excited to get started? Let’s install Express.js first!

Installing Express.js

Quick Note:  Before delving into Express, ensure Node.js is installed on your operating system.

Follow these steps to set up your Express application:

Step 1: Create a directory to run your application with this code:

mkdir Demo
cd Demo

Step 2: Use NPM to create the package.json file:

npm init --y

Note: You can use –y to quickly set default settings in the Package.json file, which you can modify later.

Step 3: Install Express.js locally:

npm install --save express

Note: Use “save” to install this package within the dependencies section.

The project’s structure will be as follows:

Project structure

Your package.json file should resemble the following:

{
"name": "Demo",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon app.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"nodemon": "^3.0.1"
},
"dependencies": {
"express": "^4.18.2"
}
}

Congrats! You’ve successfully installed Express.js.

Remember: A server is crucial to facilitate communication between clients and applications. So, up next, I’ll help you build a server with Express.js.

How to build a server with Express.js?

To build a server, we installed Express framework and created a simple server application.

Step 1: Now, we will create the file, app.js, at the root of our project’s directory:

const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(3000, () => console.log('Example app listening on port 3000!'));

Step 2: To initiate the server, open your terminal and enter the following command:

node app.js

Step 3: Initiate the server on port 3000, responding with “Hello World” to http://localhost:3000 upon browser request.

The code begins by requiring the Express module, including npm packages in the project.

Before using Express, define an instance (‘app’) to manage server-client interactions.

Step 4: Employ ‘app.get()’ to specify actions for incoming GET requests, utilizing ‘req’ and ‘res’ objects provided by the Express framework. This approach ensures efficient communication and organized handling of server responses.

Now that you’ve made a server, let’s understand two important terms:

  1. Routing
  2. Middleware

Let me explain why Express.js needs them to work well next.

1. Routing in Express.js

1.1. What is Routing?

Routing is like guiding a server on how to react when someone asks for something specific. It involves a path (like ‘/books’) and a method (like GET, PUT, POST, DELETE, etc.) in a web address.

To define the routes, refer below syntax:

app.METHOD(PATH?, HANDLER)

Routers in Express help organize code by keeping related parts in separate files. You can export and import these routes easily. This makes code more manageable.

Quick Note: In Express.js, define all routes before calling app.listen(). Typically, app.listen() is the final function executed in an Express application.

1.2. Routing Method

In web talk, HTTP is like a messenger service between clients and servers. Each route needs a handler function, deciding how the server responds. Here’s a simple example:

// GET method route
app.get('/', (req, res) => { res.send('Hello World!')});

Here, when someone requests the main page (‘/’), the server sends back a simple message, like saying ‘Hello World!’

1.3. Routing Path

Think of a routing path as a way to tell the server where clients can ask for things. For instance:

// Home page route
app.get('/home', (req, res) => {
res.send('Home Page');
});
// About page route
app.get('/about', (req, res) => {
res.send('About');
});

In the provided code, there are two endpoints, ‘/home’ and ‘/about.’ If a client requests ‘/home,’ it gets ‘Home Page’; for ‘/about,’ it gets ‘About Page.’ The default route runs on ‘/’.

1.4. Routing Parameters

Route parameters are placeholders in the URL that capture specified values. In this case, we use the req.params object, which grants access to all parameters passed in the URL.

app.get('/books/:bookId', (req, res) => {
res.send(req.params);
});

In the provided source code, the client’s request URL will be:

http://localhost:3000/books/23

Route parameter names should consist of characters ([A-Za-z0-9_]). In our application, a common use of routing parameters is for creating a 404 route.

// For invalid routes
app.get('*', (req, res) => {
res.send('404! This is an invalid URL.');
});

Now, if we start the server by typing “node app.js” in the command line and visit the URL http://localhost:3000/abcd, the server will respond with a 404 message.

Onwards to understanding Middleware!

2. Middleware functions

Middleware functions in Express have access to the request object, response object, and the next function in the request-response cycle.

Middleware functions in Express are like checkpoints. They modify requests and responses, add headers, and can end or continue the cycle. If a middleware doesn’t end it, it calls next() for the next middleware. Else the request will be left hanging.

Given below is an image that shows how middleware handles client requests and generates the desired responses:

Express.js uses middleware to process incoming requests through a series of functions. Unlike a single handler, it allows multiple functions to be added, enabling modular code and easy integration of third-party packages.

To deepen our understanding, let’s craft a custom middleware function. Consider the following code as an illustration:

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

// Simple request time logger
app.use((req, res, next) => {
console.log("A new request received at " + Date.now());
// This function call tells that more processing is
// required for the current request and is in the next middleware
function/route handler.
next(); 
});

app.get('/home', (req, res) => {
res.send('Home Page');
});

app.get('/about', (req, res) => {
res.send('About Page');
});

app.listen(3000, () => console.log('Example app listening on port 3000!'));

2.1: Setting up Middleware

To configure middleware, be it custom or from an npm module, utilize the app.use() function. It requires a mandatory callback parameter and an optional path parameter, which we omit in our case.

app.use((req, res, next) => {
console.log('A new request received at ' + Date.now());
next();
});

The next() function, supplied by Express.js, must be executed within the middleware to allow the request to proceed to the subsequent middleware. This middleware is invoked for each client request. When the server runs, you’ll observe messages in the terminal for every browser request at the / endpoint, like:

A new request received at 1467267512545

2.2: Usage of Middleware functions

Middleware functions can be used for a specific route. See the example below:

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

//Simple request time logger for a specific route
app.use('/home', (req, res, next) => {
console.log('A new request received at ' + Date.now());
next();
});

app.get('/home', (req, res) => {
res.send('Home Page');
});

app.get('/about', (req, res) => {
res.send('About Page');
});
app.listen(3000, () => console.log('Example app listening on port 3000!'));

In our example, the arrangement of middleware functions dictates their execution sequence. If we define the route app.get(‘/home’) before the middleware app.use(‘/home’), the middleware function won’t be invoked.”

Did you know?

Understanding the intricacies of your project’s architecture is a fundamental practice for effectively structuring your Express.js application. While it may be considered optional, adhering to a well-defined structure is highly advisable for optimal results.

Up next, you’ll grasp the concept!

Project Structure of an Express App

Here’s a standard structure for an Express-based web application:

project-root/
node_modules/ // This is where the packages installed are stored
config/
db.js // Database connection and configuration
credentials.js // Passwords/API keys for external services used by your app
config.js // Environment variables
models/ // For mongoose schemas
books.js
things.js
routes/ // All routes for different entities in different files
books.js
things.js
views/
index.pug
404.pug
...
public/ // All static files
images/
css/
javascript/
app.js
routes.js // Require all routes in this and then require this file in
app.js
Package.json

This pattern is called MVC, short for model-view-controller. It separates the database model, application UI, and controllers (routes) into distinct files. This design pattern ensures easy scalability for adding more routes or static files in the future, making the code more maintainable.

To sum up, skillfully using middleware functions gives developers a strong set of tools to easily add extra features, making a web app more secure and functional.

The ability to register multiple middleware functions and the adoption of a robust error-handling approach not only facilitates the smooth integration of diverse functionalities but also empowers developers to craft resilient and reliable applications.

So, to elevate your software business, connect with us at Nitor Infotech. We specialize in solving tech problems with cutting-edge solutions.

subscribe image

Subscribe to our
fortnightly newsletter!

we'll keep you in the loop with everything that's trending in the tech world.

We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it. Accept Cookie policy