DEV Community

loading...
Cover image for Let's Understand the Express.js framework

Let's Understand the Express.js framework

mikitashah profile image mikitashah Originally published at blogosphere.tech ・8 min read

Node.js has become a reliable and trusted framework for modern web application development, providing a runtime environment that allows the use of JavaScript for both client-side and server-side application code.

In this article, let us understand the basics of the Express.js framework and why should we use this framework.

Alt Text

Express is a light-weight, backend-based framework used for developing single-page, multi-page, and hybrid Node.js applications. Express is a minimal and flexible Node.js web application framework that provides a robust set of features for developing web and mobile applications. It helps to organize an application into an MVC (model-view-controller) architecture.

Every developer may have heard of an express framework earlier or later during their development phase and maybe using it knowingly or unknowingly while doing their project development life cycle

Why should I use express.js?

Express is an open-source and flexible NodeJS web app framework designed to make developing websites, web apps, & API’s much simple and easy.

You should use this so that you don’t have to repeat the same code over and over again.

Node.js is a low-level I/O mechanism that has an HTTP module. If you just use an HTTP module, a lot of work like parsing the payload, cookies, storing sessions (in memory or in Redis), selecting the right route pattern based on regular expressions will have to be re-implemented. With Express.js, it is just there for you to use.


There are quite a few Node.js frameworks built based upon this express framework or inspired by its concepts. I have listed down a few for reference.

  • Kraken: Secure and scalable layer that extends Express by providing structure and convention.
  • LoopBack: Highly-extensible, open-source Node.js framework for quickly creating dynamic end-to-end REST APIs.
  • Sails: MVC framework for Node.js for building practical, production-ready apps.
  • NestJs: A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications on top of TypeScript & JavaScript (ES6, ES7, ES8)
  • ItemsAPI: Search backend for web and mobile applications built on Express and Elasticsearch.
  • KeystoneJS: Website and API Application Framework / CMS with an auto-generated React.js Admin UI.

Let us create our first Hello World app using express.js in 5 simple steps as listed below!

Step1: Install express

Express framework can be installed using the Node Package Manager (NPM) with command as follows

npm install express
Enter fullscreen mode Exit fullscreen mode

Step 2: Import express module

Create a file called server.js and import express module using the following syntax.

const express = require(‘express’)
Enter fullscreen mode Exit fullscreen mode

Step 3: Create an object

Create an object which will hold the value of the express module. In our case, the ‘app’ is the object holding instance of the express module.

let app = express();
Enter fullscreen mode Exit fullscreen mode

Step 4: Create a callback function

Create a GET callback function using the object we created in the above step. This function accepts two params ‘req’ i.e. request which the client browser can send and ‘res’ i.e. response which our server file will send back to the client.
In our case, we will just send the string ‘Hello World’ back to the client browser.

app.get(‘/‘,function (req, res){
res.send(“Hello World”);
});
Enter fullscreen mode Exit fullscreen mode

Step 5: Listen to the client request

Listen on port 3000 which means every time the client browser hits on this port number, then our server will return back string response.

app.listen(3000, function(){
});
Enter fullscreen mode Exit fullscreen mode

Hurray! We finished writing the code! Let us run our first client-server application.

For that, first of all, we would need to run our server, which will listen to any request hitting on port 3000 from the browser.

Go to command prompt/ terminal and type the following command
npm node server.js

Now, open the browser on your machine, and type http://localhost:3000

Voila, you can see ‘Hello World’ on your browser.


Notable features of using Express.js

Feature 1: Routing

Routing refers to how an application’s endpoints (URIs) respond to client requests.

You can define routing using methods of the Express app object that correspond to HTTP methods like app.get() to handle GET requests and app.post to handle POST requests. You can also use app.all() to handle all HTTP methods and app.use() to specify middleware as the callback function.

We will study more about middlewares in the below article.

These routing methods specify a callback function (also referred to as handler functions) which is called when the application receives a request to the specified route (endpoint) and HTTP method.

In other words, the application listens for requests that match the specified route(s) and method(s), and when it detects a match, it calls the specified callback function.

Routing methods can have more than one callback function as arguments. With multiple callback functions, it is important to provide next as an argument to the callback function and then call next() within the body of the function to hand off control to the next callback.

var express = require(‘express’)
var app = express()
// respond with “Learning Express” when a GET request is made to the homepage
app.get(‘/’, function (req, res) {
res.send(‘Learning Express’)
   // Logic
})
A route method is derived from one of the HTTP methods and is attached to an instance of the express class.
// GET method
app.get(‘/’, function (req, res) {
    res.send(‘You called GET request’)
})
// POST method
app.post(‘/’, function (req, res) {
   res.send(‘You called POST request’)
})
Enter fullscreen mode Exit fullscreen mode

Route paths, in combination with a request method, define the endpoints at which requests can be made. Route paths can be strings, string patterns, or regular expressions.

app.get(‘/’, function (req, res) {
   res.send(‘this is default index page’)
})
Enter fullscreen mode Exit fullscreen mode

Now say, for example, you want to call the AboutUs page, following is the way

app.get(‘/aboutUs’, function (req, res) {
    res.send(‘About Us’)
})
Enter fullscreen mode Exit fullscreen mode

Route parameters are named URL segments that are used to capture the values specified at their position in the URL. The captured values are populated in the req.params object, with the name of the route parameter specified in the path as their respective keys.
Let us say, for example, if you want to perform some function when you have bookId and userId passed, you can define the endpoint URI as follows
Request URL: http://localhost:3000/users/34/books/8989

app.get(‘/users/:userId/books/:bookId’, function (req, res) {
   res.send(req.params)
})
Enter fullscreen mode Exit fullscreen mode

Feature 2: Middlewares

Middleware, as the name implies, sits in the middle of a raw request sent from the client-side browser and the final intended routing logic designed by your server-side application. It basically lets you configure how your express application should work. Middleware functions have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle. The next function is a function in the Express router which, when invoked, executes the middleware succeeding the current middleware.

Middleware functions can perform the following tasks:

  • Execute any code.
  • Make changes to the request and the response objects.
  • End the request-response cycle.
  • Call the next middleware in the stack.

Some common tasks include checking for user login status, validating user authority, or preventing cross-site attacks that are best extracted as middleware.

If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.

Here is a simple example of a middleware function called logger. This function just prints "Logging" when a request to the app passes through it. The middleware function is assigned to a variable named logger.

To load the middleware function, call _app.use(), specifying the middleware function._

For example, the following code loads the logger middleware function before the route to the root path (/)

const express = require(‘express’);
let app = express()
let logger = function (req, res, next) {
    console.log(‘Logging’)
    next()
}
app.use(logger)
app.get(‘/’, function (req, res) {
    res.send(‘My home page’)
})
app.listen(3000)
Enter fullscreen mode Exit fullscreen mode

Every time the app receives a request, it prints the message Logging to the terminal.

The order of middleware loading is important. Middleware functions that are loaded first are also executed first.

If the logger was loaded after the route to the root path, the request never reaches it and the app doesn’t print "Logging", because the route handler of the root path terminates the request-response cycle.

The middleware function logger simply prints a message, then passes on the request to the next middleware function in the stack by calling the next() function.

You can use third-party middleware to add functionality to Express apps.

The following example illustrates installing and loading the third-party cookie-parsing middleware function called cookie-parser.

var app = express();
app.use(cookieParser());
app.use(bodyParser());
app.use(logger());
app.use(authentication());
app.get(‘/’, function (req, res) {
     // …
});
app.listen(3000);
Enter fullscreen mode Exit fullscreen mode

An Express application is essentially Node.js with a host of middleware functions, whether you want to customize your own middleware or take advantage of the built-in middlewares of the framework, Express made the process natural and intuitive.

Feature 3: Templating

A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values and transforms the template into an HTML file sent to the client.

This approach makes it easier to design an HTML page.
Some popular template engines that work with Express are Pug, Mustache, and EJS. The Express application generator uses Jade as its default, but it also supports several others.

After the view engine is set, you don’t have to specify the engine or load the template engine module in your app;

app.set(‘view engine’, ‘pug’)
Enter fullscreen mode Exit fullscreen mode

Template engines allow the developer to embed backend variables into HTML files, and when requested the template file will be rendered to plain HTML format with the variables interpolated with their actual values.

Feature 4: Error-handling

Define error-handling middleware functions in the same way as other middleware functions, except error-handling functions, have four arguments instead of three: (err, req, res, next)

app.use(function (err, req, res, next) {
     console.error(err.stack)
     res.status(500).send(‘Something broke!’)
})
Enter fullscreen mode Exit fullscreen mode

You can define error-handling middleware at last, after defining other app.use() and routes call.

var bodyParser = require(‘body-parser’)
var methodOverride = require(‘method-override’)
app.use(bodyParser.urlencoded({
    extended: true
}))
app.use(bodyParser.json())
app.use(methodOverride())
app.use(function (err, req, res, next) {
    // logic
})
Enter fullscreen mode Exit fullscreen mode

Express.js simplifies development and makes it easier to write secure, modular, and fast applications. You can anytime do all that in plain old Node.js, but some bugs can (and will) surface, including security concerns (eg. not escaping a string properly), etc. Whenever we think about developing a scalable web application using NodeJS then express.js will be the recommended framework to be used.


Are there any cons of using Express.js?

Express is a minimal, un-opinionated framework. It doesn’t apply any of the prevalent design patterns such as MVC, MVP, MVVM, or whatever is trending out of the box. For fans of simplicity, this is a big plus among all other frameworks because you can build your application with your own preference and no unnecessary learning curve. This is especially advantageous when creating a new personal project with no historical burden, but as the project or developing team grows, lack of standardization may lead to extra work for project/code management, and worst-case scenario it may lead to the inability to maintain.


Hope this article helps you understand some basics of how and why Express.js is useful.

Discussion

pic
Editor guide
Collapse
pika1998 profile image
Prafulla Raichurkar

Great article, I would like to share a GitHub action which I created

GitHub logo Pika1998 / express-autodocs

A GitHub action which automatically generates documentation for your express APIs.



Contributions

💡 Introduction

This action automatically scans for express APIs in your codebase and generates a documentation website


How to add to your workflow

To add this action to your workflow simply modify your workflows main.yml file.

# This is a basic workflow to help you get started with Express AutoDocs Action
name: Express AutoDocs.
# This specifies when the action should occur
on
  push
    branches: [master]

jobs:
  generate_docs_job:
    runs-on: ubuntu-latest
    name: Generating Docs
    steps:
      # this step checks out the master branch of your repo using checkout action.
      - name: Checks out the repository
        id: checksout-repository
        uses: actions/checkout@v2
        with:
          repository: ""
      # this step generates the docs
      - name: Generating Docs.
        id: reading-file
        uses: Pika1998/express-autodocs@v0.0.1
      # Use the output from the `hello` step
      - name: Get the output time
        run

This action scans for express APIs and generates automatic documentation using them, I feel it would add more value to this article :)

Collapse
mikitashah profile image
mikitashah Author

Sure, if it helps other developers with the combined documentation, then I have no issues.