Search code examples
node.jsexpressroutesmiddleware

Middleware next() routeHandler


I am currently reading this article

At the section Middleware the author is explaining very well what the benefit of next() is.

Writing this

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);

By using next() can be much cleaner

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);

But what I don't understand is: How does next() know if it should go as next in the /dashboard or in the /profile route handler ?


Solution

  • Just go to the next route in the "router handle list". The order is very important, in your example, the router list will look like GET /* (any thing) -> GET /* (any thing) -> GET /dashboard -> GET /profile.

    Your request from the browser is GET /profile, check the method and path by order:

    is match anything -> Yes, do something, next

    is match anything -> Yes, do something, next

    is match GET /dashboard -> No, not execute dashboard handler, check next router in the array.

    is match GET /profile -> Yes, do something, call httpResponse.send -> finished.

    If you register a route before app.get("/*", route to check login, it will pass without check login

    ...
    app.get("/secret", function(httpRequest, httpResponse, next){
    
            httpResponse.send("Tada!!!");
    });
    
    app.get("/*", function(httpRequest, httpResponse, next){
    
        if(checkLogin())
        {
            next();
        }
        else
        {
            httpResponse.send("You are not logged in!!!");
        }
    })
    ...