Let's Understand the Express.js framework
Tags: node, framework, express, javascript
Published: 2020-09-20 13:45:57

>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](https://dev-to-uploads.s3.amazonaws.com/i/8qarabsc4dm2roism7pm.png)

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
```
#### Step 2: Import express module
Create a file called server.js and import express module using the following syntax.
```
const express = require(‘express’)
```
#### 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();
```
#### 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”);
});
```
#### 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(){
});
```
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’)
})
```
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’)
})
```
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’)
})
```
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)
})
```

#### 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)
```
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);
```
>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’)
```
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!’)
})
```
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
})
```
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.