QNimate

  • CoursesVideos
  • WP PremiumPlugins
  • DemosLab
  • Home
  • QIdea
  • QTrack
Home Carbon Ads Express.js Middleware Tutorial

Express.js Middleware Tutorial

node-express-sendfile

Developers who are new to Express often get confused with the difference between route handler and middleware. Therefore they also get confused with the difference between app.use(), app.all(), app.get(), app.post(), app.delete() and app.put() methods.

In this tutorial I will explain the exact difference between a middleware and route handler. And also how to use the app.use(), app.all(), app.get(), app.post(), app.delete() and app.put() methods correctly.

Route Handler

app.all(), app.get(), app.post(), app.delete() and app.put() methods are all used to define routes. A route is used to handle a HTTP request. A route is a combination of a path and callback, which is executed when a request’s path is matches. The callback is called as the route handler.

The difference between app.all(), app.get(), app.post(), app.delete() and app.put() methods is that they handle different types of HTTP requests. For example: app.get() handlers only GET requests whereas app.all() can handle GET, POST and so on.

Here is an example of how to define a route:

var app = require("express")();

app.get("/", function(httpRequest, httpResponse, next){
    httpResponse.send("Hello World!!!!");
});

app.listen(8080);

Every route handler get a reference to the request and response object of the HTTP request that is currently being served.

There can be multiple route handlers executed for a single HTTP request. Here is an example:

var app = require("express")();

app.get("/", function(httpRequest, httpResponse, next){
    httpResponse.write("Hello");
    next();
});

app.get("/", function(httpRequest, httpResponse, next){
    httpResponse.write(" World !!!");
    httpResponse.end();
});

app.listen(8080);

Here the first handle writes some response and then calls next(). The next() method is used to call the next route handler match the route path.

A route handler must end the request or call the next route handler.

We can also pass multiple route handlers to a single call to app.all(), app.get(), app.post(), app.delete() and app.put() methods. Here is an example to demonstrate this:

var app = require("express")();

app.get("/", function(httpRequest, httpResponse, next){
    httpResponse.write("Hello");
    next();
}, function(httpRequest, httpResponse, next){
    httpResponse.write(" World !!!");
    httpResponse.end();
});

app.listen(8080);

Middleware

A Middleware is a callback that sits on top of the actual request handlers. It takes the same parameters as a route handler.

To understand middleware let’s take an example site which has a dashboard and profile page. To visit these pages the user must login. Requests to these pages are also logged. Here is how the route handler for these pages would look like:

var app = require("express")();

function checkLogin()
{
    return false;
}

function logRequest()
{
    console.log("New request");
}

app.get("/dashboard", function(httpRequest, httpResponse, next){

    logRequest();

    if(checkLogin())
    {
        httpResponse.send("This is the dashboard page");
    }
    else
    {
        httpResponse.send("You are not logged in!!!");
    }
});

app.get("/profile", function(httpRequest, httpResponse, next){

    logRequest();

    if(checkLogin())
    {
        httpResponse.send("This is the dashboard page");
    }
    else
    {
        httpResponse.send("You are not logged in!!!");
    }
});

app.listen(8080);

Here the problem is that there is a lot of repeating code i.e., we had to logRequest() and checkLogin() function calls multiple time. This also makes it difficult to update code. So to deal with this problem we can write a common route for these two paths. Here is the rewritten code:

var app = require("express")();

function checkLogin()
{
    return false;
}

function logRequest()
{
    console.log("New request");
}

app.get("/*", function(httpRequest, httpResponse, next){
    logRequest();
    next();
})

app.get("/*", function(httpRequest, httpResponse, next){

    if(checkLogin())
    {
        next();
    }
    else
    {
        httpResponse.send("You are not logged in!!!");
    }
})

app.get("/dashboard", function(httpRequest, httpResponse, next){

        httpResponse.send("This is the dashboard page");

});

app.get("/profile", function(httpRequest, httpResponse, next){

        httpResponse.send("This is the dashboard page");

});

app.listen(8080);

Here is the code looks a lot cleaner and is easier to maintain and update. Here the first two defined route handler are called as middleware because they are not handling the request rather responsible for pre-processing of the request.

Express provides us app.use() method which is specifically used to define middlewares. app.use() method may seem similar to app.all() but there are a lot of differences between them which makes app.use() perfect for declaring middlewares. Let’s see how app.use() method works:

app.use()

Here are the difference between app.use() and app.all():

Callback

app.use() takes only one callback whereas app.all() can take multiple callbacks.

Path

app.use() only see whether url starts with specified path where app.all() will match complete path.

Here is an example to demonstrate this:

app.use( "/product" , mymiddleware);
// will match /product
// will match /product/cool
// will match /product/foo

app.all( "/product" , handler);
// will match /product
// won't match /product/cool   <-- important
// won't match /product/foo    <-- important

app.all( "/product/*" , handler);
// won't match /product        <-- Important
// will match /product/cool
// will match /product/foo
next()

next() call inside a middleware invokes the next middleware or route handler depending on whichever is declared next. But next() call inside a route handler invokes the next route handler only. If there is a middleware next then it’s skipped. Therefore middlewares must be declared above all route handlers.

Here is an example to demonstrate this:

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

app.use(function frontControllerMiddlewareExecuted(req, res, next){
  console.log('(1) this frontControllerMiddlewareExecuted is executed');
  next();
});

app.all('*', function(req, res, next){
  console.log('(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next');
  next();
});

app.all('/hello', function(req, res, next){
  console.log('(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next');
  next();
});

app.use(function frontControllerMiddlewareNotExecuted(req, res, next){
  console.log('(4) this frontControllerMiddlewareNotExecuted is not executed');
  next();
});

app.get('/hello', function(req, res){
  console.log('(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response');
  res.send('Hello World');
});

app.listen(80);

Now we saw the the uniqueness of the app.use() method and why it is used to declare middlewares. Let’s rewrite our example site code:

var app = require("express")();

function checkLogin()
{
    return false;
}

function logRequest()
{
    console.log("New request");
}

app.use(function(httpRequest, httpResponse, next){
    logRequest();
    next();
})

app.use(function(httpRequest, httpResponse, next){

    if(checkLogin())
    {
        next();
    }
    else
    {
        httpResponse.send("You are not logged in!!!");
    }
})

app.get("/dashboard", function(httpRequest, httpResponse, next){

        httpResponse.send("This is the dashboard page");

});

app.get("/profile", function(httpRequest, httpResponse, next){

        httpResponse.send("This is the dashboard page");

});

app.listen(8080);

Oct 18, 2015Narayan Prusty
Storing Data Locally in a Intel XDK AppES6 Reflect API Tutorial
Comments: 14
  1. Ravi Sankar
    5 years ago

    if (err) {
    return next(err)
    }

    What it means in express. How “next” handling errors

    ReplyCancel
  2. Joe
    6 years ago

    Started off nicely, but then you assume a lot.. Some things need more explanation, or just a statement to say how things function in the express world.

    For example, how do i know which next() function is going to be called if I have 4 functions, is it from the top of the page going down, or is it by magic?

    Your app.use() example starts with a route

    app.use( "/product" , mymiddleware);

    but then you dropped the route in the next example without mentioning why?

    app.use(function frontControllerMiddlewareExecuted(req, res, next){
    ..etc...
    });

    ReplyCancel
    • Deon
      5 years ago

      2500 euros une prof ? Avec l&tuaso;aggrégqrion et une certaine ancienneté, ou pas mal d’heures supplémentaires. Ce n’est pas la moyenne des profs.Un certifié en début de carrière, c’est 1300-1400. Avec 10 ans d’ancienneté, à peu près 1800.

      ReplyCancel
  3. JK
    6 years ago

    Thanks for your excellent tutorial!I think it necessary to understand.

    ReplyCancel
  4. Ganesh
    6 years ago

    hey Narayan,
    great effort and thank you so much for the wonderful article.
    amazing work. this article solved many doubts that i had.
    thank you

    ReplyCancel
  5. Arne
    6 years ago

    First of all be consistent of writing your semicolons, I know JavaScript has ASI, but when trying to teach people JS while writing blogposts, be 100% correct, every time.

    Secondly, please do not write JavaScript in a C-like manner ({ – on the next line) this fucks up when you are trying to return objects, and a lot of beginning JavaScript programmers (especially coming from C-like languages) have trouble understanding why.

    Content-wise this blogpost is correct, but be aware that on “style” level this needs a lot of work.

    Keep getting better and thank you for sharing!!

    ReplyCancel
    • Rajesh
      6 years ago

      Hi Arne
      If you have any proper syntactical blogs, please post it. If not shut your mouth and close fuck of things.

      ReplyCancel
  6. Maham
    6 years ago

    Hey, Narayan!

    Thank you for sharing your knowledge and explaining all this in an easy to understand way.
    This really helped. Thanks again! (Y)

    ReplyCancel
  7. James Lo
    6 years ago

    I seriously wish i had read this when I first learned node and express!

    ReplyCancel
    • Norm
      5 years ago

      Bienvenido Bob, un lujazo de artículo de presentación. Y además un buen tanto de Little & friends al fichar a un gran fotógrafo aviones que “hacen mucho ruido y van pintados de gris”. Tu foto del CX con las bengalas es realmente espectacular y muy muy famosa dentro y fuera de Esneu±aEnhorabÃapa y gracias !!!DaiSan

      ReplyCancel
  8. Hemadri
    6 years ago

    Thanks for this advanced and useful info.. This page helped me to understand few concepts from the scratch..

    ReplyCancel
    • Henrietta
      6 years ago

      Keep these arlteics coming as they’ve opened many new doors for me.

      ReplyCancel
  9. Lucas
    6 years ago

    Thanks for the tutorial i am glad for the community we have on internet, willing to share knowledge. Nice job =).

    ReplyCancel
  10. Arun
    7 years ago

    Hi Narayan,
    Thanks for this tutorial. The difference between middleware and handler is clearly explained here.

    ReplyCancel

Leave a Reply Cancel reply

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Narayan Prusty

I am a software engineer specialising in Blockchain, DevOps and Go/JavaScript. This is my personal blog where I write about things that I learn and feel interesting to share.

Image7 years ago 15 Comments Node.js
Share this
0
GooglePlus
0
Facebook
0
Twitter
0
Linkedin
  • Route Handler
  • Middleware
Related Articles
  • Streaming File Uploads to Storage Server with Node.js
  • npm Tutorial For Non Node.js Developers
  • How To Integrate Forms On WordPress
  • Display Loading Indicator In Status Bar using Intel XDK
  • WordPress Check if Gravatar Exists
Our Sponsor
My Books

2014 - 2015 © QNimate
All tutorials MIT license