Making Your Own Express Middleware

by:

Web Development


Express is a common way to display static routes to a user. It is even more commonly used to create APIs for Node.JS. In Express, it’s easy to define a URL and what will happen at that URL. We can also define middleware, which runs before the final request is returned. This can let us to alter the request and do it in a standard way across many routes.

If you’ve used Express, you may have already used pre-built middleware like bodyParser or jsonParser. In this guide, let’s look at how you can create your own custom middleware.

Creating a Middleware in Express

A middleware is simply something that data passes through on its way to its actual end location. Consider you have a route like this:

import express from 'express';
const app = express()

app.get('/home/', (req, res, next) => 
    if(req.getRoute == true) 
        res.status(200).send("Hello world!")
    
    else 
        res.status(200).send("Goodbye world!")
    
)

In this example, if the request or req has the property getRoute set to true, we will show a different set of text. By default, HTTP requests do not have a property called getRoute. Of course, it would be easy to set it within /home/ itself, but imagine you had multiple requests, all depending on this one getRoute property:

import express from 'express';
const app = express()

app.get('/home/', (req, res, next) => 
    if(req.getRoute == true) 
        res.status(200).send("Hello world!")
    
    else 
        res.status(200).send("Goodbye world!")
    
)

app.get('/home/article', (req, res, next) => 
    if(req.getRoute == false) 
        res.status(200).send("This is my article");
    
    else 
        res.status(400).send("ERROR OCCURRED");
    
)

Now we have a situation where a middleware might make sense. There are two ways to define a middleware – with use(), or via a function. Let’s look at use() first.

use() As a Middleware

Considering our previous example, we can use use() to write a function that runs on every route. This is, therefore, a general middleware, which will run any time the user goes to any valid route on your server. Here is an example where we define getRoute within a use() middleware:

app.use((req, res, next) => 
    // Add getRoute to our request object
    req.getRoute = true;
    // Next tells express to now go to the next valid function.
    next();
);

app.get('/home/', (req, res, next) => 
    if(req.getRoute == true) 
        res.status(200).send("Hello world!")
    
    else 
        res.status(200).send("Goodbye world!")
    
)

app.get('/home/article', (req, res, next) => 
    if(req.getRoute == false) 
        res.status(200).send("This is my article");
    
    else 
        res.status(400).send("ERROR OCCURRED");
    
)

Using this middleware, we can add getRoute to our request, and it’ll now be available to /home/ and /home/article. It’ll also be available to any other route on your server. When we call next(), it tells Express to go onto the next valid route. For example, if the user went to /home/, then first our middleware would be called, and then since we called next() within it, Express would go to the /home/ route, as we have it defined.

Use Case: API Verification

A trick I often use for generalized middleware is to split functionality that applies to certain HTTP methods. For example, if I wanted to apply an API verification function to all POST requests, I can easily do that in a standard middleware used by the entire app:

import  apiVerification  from './util.js'
app.use(async (req, res, next) => 
    // Here, apiVerification is a function that returns true if the right request is sent.
    // We only want to apply it to POST methods, though, so lets add that to our middleware.
    if(req.method == "POST") 
        let verifyCredentials = await apiVerification(req);
        if(verifyCredentials) 
            next();
        
        else 
            res.status(400).send("ERROR OCCURRED");
        
    
    else 
        // For everything else, like "GET", go to next valid route.
        next();
    
);

This is a perfect way to add a standard verification method to all your POST routes without having to redefine and recall apiVerification every time. If apiVerification fails, the user is given an error message instead. For other methods like GET, this apiVerification step is skipped.

Specific Middlewares

Sometimes, you only want a middleware to apply to specific routes rather than generally to everything. For that, we need to define them in a function. Using our previous example, we can create a function for req.getRoute, and apply it to only the routes we want to:

let setGetRoute = (req, res, next) => 
    req.getRoute = true;


app.get('/home/', setGetRoute, (req, res, next) => 
    if(req.getRoute == true) 
        res.status(200).send("Hello world!")
    
    else 
        res.status(200).send("Goodbye world!")
    
)

app.get('/home/article', (req, res, next) => 
    if(req.getRoute == undefined) 
        res.status(200).send("This is my article");
    
    else 
        res.status(400).send("ERROR OCCURRED");
    
)

Now req.getRoute will only be available to app.get('/home/'.., since we only added that function to that route (app.get('/home/', setGetRoute...). For /home/article, req.getRoute will not be available.

This is quite useful when we only want to provide certain functionality in specific situations.

Middlewares are a¬†powerful part of Express and let us process requests differently r apply certain functions to all requests. I hope you’ve enjoyed this article.



Source link

Leave a Reply

Your email address will not be published.