DotEnv, Router, MVC and Middleware

Syed Aquib AliSyed Aquib Ali
4 min read

DotEnv

Environment variables are variables that are set outside of a program, often through a cloud provider or operating system.

In NodeJS, environment variables are a great way to securely and conveniently configure things that do not change often, like URL, authentication keys, and passwords.

Environment variables are supported out of the box with Node and are accessible via the env object (which is a property of the process global object).

DotEnv is a lightweight npm package that automatically loads environment variables from a .env file into the process.env object.

To use DotEnv, first install it using the command npm i dotenv. Then create a .env file and create any kind of variable, let us create a PORT variable:

// .env
PORT=5000
  • One thing to note, there should be no unnecessary spaces or enters, only go to new line when it is required to create new variable.

Then in your app require and configure the package:

// index.js
const dotenv = require('dotenv');

dotenv.config({
    path: './.env',
});

const app = express();

const PORT = process.env.PORT;

app.listen(PORT, () => {
    console.log(`listening on port: ${PORT}`);
});

Router

Use the express.Router class to create a modular, mountable route handlers. A router instace is a complete middleware and routing system, for this reason it is often referred to as a mini-app.

const router = require('express').Router();

router.post('/post', (req, res) => {
    res.json({
        status: 'success',
    });
});

router.get('/all/post', (req, res) => {
    res.json({
        status: 'success',
    });
});

module.exports = router;
  • There can be multiple routers in one file such as shown above.

  • All of the routers will be exported in one object router.

MVC Architecture

MVC (Model, View, Controller) is simply a design or architectural pattern used in software engineering. While this is not a hard rule, but this pattern helps developers focus on a particular aspect of their application, one step at a time.

The main goal of MVC is to split large applications into specific sections that have their own individual purpose.

Here is a visual demonstration of how it works:

  1. Model

As the name implies, a model is a design or structure. In the case of MVC, the model determines how a database is structured, defining a section of the application that interacts with the database. this is where we will define the properties of a user that will be stored in our database.

  1. View

The view is where end users interact within the application. Simply put, this is where all the HTML template files go.

  1. Controller

The controller ineracts with the model and serves the response and functionality to the view. When an end user makes a request, it is sent to the controller which interacts with the databse.

Middleware

Express is a routing and middleware web framework that has minimal functionality of its own. An Express application is essentially a series of middleware function calls.

Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application's request-response cycle. The next middleware function is commonly denoted by a variable named (next).

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 function in the stack.

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.

  • This example shows a middleware function with no mount path. The function is executed every time the app receives a request.
app.use((req, res, next) => {
    console.log(req.method, req.url, new Date().toTimeString());
    next();
});
  • This example shows a middleware function mounted on the /user/:id path. The function is executed for any type of HTTP request on the /user/:id path.
app.use('/user/:id', (req, res. next) => {
    console.log(`Request Type: ${req.method}`);
    next();
});
  • This example shows a route and its handler function (middleware system). The function handles GET requests to the /user/:id path.
app.get('/user/:id', (req, res, next) => {
    res.send('USER');
});
  • Here is an example of loading a series of middleware functions at a mount point, with a mount path. it illustrates a middleware sub-stack that prints request info for any type of HTTP request to the /user/:id path.
app.use(
    '/user/:id',
    (req, res, next) => {
        console.log(`Request URL: ${req.originalUrl}`);
        next();
    },
    (req, res, next) => {
        console.log(`Request Type: ${req.method}`);
        next();
    }
);
  • Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the /user/:id path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle.

    This example shows a middleware sub-stack that handles GET requests to the /user/:id path.

app.get('/user/:id', (req, res, next) => {
    console.log(`ID: ${req.params.id}`);
    next();
});
0
Subscribe to my newsletter

Read articles from Syed Aquib Ali directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Syed Aquib Ali
Syed Aquib Ali

I am a MERN stack developer who has learnt everything yet trying to polish his skills 🥂, I love backend more than frontend.