What does middleware and app.use actually mean in Expressjs?

前端 未结 9 1281
小蘑菇
小蘑菇 2020-11-29 14:55

Almost every Express app I see has an app.use statement for middleware but I haven\'t found a clear, concise explanation of what middleware actually is and what

相关标签:
9条回答
  • 2020-11-29 14:58

    middleware

    I'm halfway through separating the concept of middleware in a new project.

    Middleware allows you to define a stack of actions that you should flow through. Express servers themselves are a stack of middlewares.

    // express
    var app = express();
    // middleware
    var stack = middleware();
    

    Then you can add layers to the middleware stack by calling .use

    // express
    app.use(express.static(..));
    // middleware
    stack.use(function(data, next) {
      next();
    });
    

    A layer in the middleware stack is a function, which takes n parameters (2 for express, req & res) and a next function.

    Middleware expects the layer to do some computation, augment the parameters and then call next.

    A stack doesn't do anything unless you handle it. Express will handle the stack every time an incoming HTTP request is caught on the server. With middleware you handle the stack manually.

    // express, you need to do nothing
    // middleware
    stack.handle(someData);
    

    A more complete example :

    var middleware = require("../src/middleware.js");
    
    var stack = middleware(function(data, next) {
        data.foo = data.data*2;
        next();
    }, function(data, next) {
        setTimeout(function() {
            data.async = true;
            next();
        }, 100)
    }, function(data) {
        console.log(data);
    });
    
    stack.handle({
        "data": 42
    })
    

    In express terms you just define a stack of operations you want express to handle for every incoming HTTP request.

    In terms of express (rather than connect) you have global middleware and route specific middleware. This means you can attach a middleware stack to every incoming HTTP requests or only attach it to HTTP requests that interact with a certain route.

    Advanced examples of express & middleware :

    // middleware 
    
    var stack = middleware(function(req, res, next) {
        users.getAll(function(err, users) {
            if (err) next(err);
            req.users = users;
            next();  
        });
    }, function(req, res, next) {
        posts.getAll(function(err, posts) {
            if (err) next(err);
            req.posts = posts;
            next();
        })
    }, function(req, res, next) {
        req.posts.forEach(function(post) {
            post.user = req.users[post.userId];
        });
    
        res.render("blog/posts", {
            "posts": req.posts
        });
    });
    
    var app = express.createServer();
    
    app.get("/posts", function(req, res) {
       stack.handle(req, res); 
    });
    
    // express
    
    var app = express.createServer();
    
    app.get("/posts", [
        function(req, res, next) {
            users.getAll(function(err, users) {
                if (err) next(err);
                req.users = users;
                next();  
            });
        }, function(req, res, next) {
            posts.getAll(function(err, posts) {
                if (err) next(err);
                req.posts = posts;
                next();
            })
        }, function(req, res, next) {
            req.posts.forEach(function(post) {
                post.user = req.users[post.userId];
            });
    
            res.render("blog/posts", {
                "posts": req.posts
            });
        }
    ], function(req, res) {
       stack.handle(req, res); 
    });
    
    0 讨论(0)
  • 2020-11-29 14:58

    =====Very very simple explanation=====

    Middlewares are often used in the context of Express.js framework and are a fundamental concept for node.js . In a nutshell, Its basically a function that has access to the request and response objects of your application. The way I'd like to think about it, is a series of 'checks/pre-screens' that the request goes through before the it is handled by the application. For e.g, Middlewares would be a good fit to determine if the request is authenticated before it proceeds to the application and return the login page if the request is not authenticated or for logging each request. A lot of third-party middlewares are available that enables a variety of functionality.

    Simple Middleware example:

    var app = express();
    app.use(function(req,res,next)){
        console.log("Request URL - "req.url);
        next();
    }
    

    The above code would be executed for each request that comes in and would log the request url, the next() method essentially allows the program to continue. If the next() function is not invoked, the program would not proceed further and would halt at the execution of the middleware.

    A couple of Middleware Gotchas:

    1. The order of middlewares in your application matters, as the request would go through each one in a sequential order.
    2. Forgetting to call the next() method in your middleware function can halt the processing of your request.
    3. Any change the req and res objects in the middleware function, would make the change available to other parts of the application that uses req and res
    0 讨论(0)
  • 2020-11-29 15:02

    Keep things simple, man!

    Note: the answer is related to the ExpressJS builtin middlware cases, however there are different definitions and use cases of middlewares.

    From my point of view, middleware acts as utility or helper functions but its activation and use is fully optional by using the app.use('path', /* define or use builtin middleware */) which don't wants from us to write some code for doing very common tasks which are needed for each HTTP request of our client like processing cookies, CSRF tokens and ..., which are very common in most applications so middleware can help us do these all for each HTTP request of our client in some stack, sequence or order of operations then provide the result of the process as a single unit of client request.

    Example:

    Accepting clients requests and providing back responses to them according to their requests is the nature of web server technology.

    Imagine if we are providing a response with just "Hello, world!" text for a GET HTTP request to our webserver's root URI is very simple scenario and don't needs anything else, but instead if we are checking the currently logged-in user and then responding with "Hello, Username!" needs something more than usual in this case we need a middleware to process all the client request metadata and provide us the identification info grabbed from the client request then according to that info we can uniquely identify our current user and it is possible to response to him/her with some related data.

    Hope it to help someone!

    0 讨论(0)
  • 2020-11-29 15:04

    I add a late answer to add something not mentioned in the previous answers.

    By now it should be clear that middleware is/are function(s) run between the client request and the server answer. The most common middleware functionality needed are error managing, database interaction, getting info from static files or other resources. To move on the middleware stack the next callback must be called, you can see it in the end of middleware function to move to the next step in the flow.

    You can use the app.use approach and have a flow like this:

    var express = require('express'),
        app = express.createServer(),                                                                                                                                                 
        port = 1337;
    
    function middleHandler(req, res, next) {
        console.log("execute middle ware");
        next();
    }
    
    app.use(function (req, res, next) {
        console.log("first middle ware");                                                                                                             
        next();
    });
    
    app.use(function (req, res, next) {
        console.log("second middle ware");                                                                                                             
        next();
    });
    
    app.get('/', middleHandler, function (req, res) {
        console.log("end middleware function");
        res.send("page render finished");
    });
    
    app.listen(port);
    console.log('start server');
    

    but you can also use another approach and pass each middleware as function arguments. Here is a example from the MooTools Nodejs website where midleware gets the Twitter, Github and Blog flow before the response is sent back to the client. Note how the functions are passed as arguments in app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){. Using app.get will only be called for GET requests, app.use will be called for all requests.

    // github, twitter & blog feeds
    var githubEvents = require('./middleware/githubEvents')({
        org: 'mootools'
    });
    var twitter = require('./middleware/twitter')();
    var blogData = require('./blog/data');
    function getLatestBlog(req, res, next){
        blogData.get(function(err, blog) {
            if (err) next(err);
            res.locals.lastBlogPost = blog.posts[0];
            next();
        });
    }
    
    // home
    app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
        res.render('index', {
            title: 'MooTools',
            site: 'mootools',
            lastBlogPost: res.locals.lastBlogPost,
            tweetFeed: res.locals.twitter
        });
    });
    
    0 讨论(0)
  • 2020-11-29 15:06

    Middleware is a subset of chained functions called by the Express js routing layer before the user-defined handler is invoked. Middleware functions have full access to the request and response objects and can modify either of them.

    The middleware chain is always called in the exact order in which it has been defined, so it is vital for you to know exactly what a specific piece of middleware is doing.
    Once a middleware function finishes, it calls the next function in the chain by invoking its next argument as function.
    After the complete chain gets executed,the user request handler is called.

    0 讨论(0)
  • 2020-11-29 15:08

    expressjs guide has pretty neat answer to your question, I highly recommend you to read that, I am posting a short snippet of the guide, the guide is quite good.

    Writing middleware for use in Express apps

    Overview

    Middleware functions are functions that 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.

    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.

    Example

    Here is an example of a simple “Hello World” Express application. The remainder of this article will define and add two middleware functions to the application: one called myLogger that prints a simple log message and another called requestTime1 that displays the timestamp of the HTTP request.

    var express = require('express')
    var app = express()
    
    app.get('/', function (req, res) {
      res.send('Hello World!')
    })
    
    app.listen(3000)   
    

    Middleware function myLogger

    Here is a simple example of a middleware function called “myLogger”. This function just prints “LOGGED” when a request to the app passes through it. The middleware function is assigned to a variable named myLogger.

    var myLogger = function (req, res, next) {
      console.log('LOGGED')
      next()
    }
    

    Notice the call above to next(). Calling this function invokes the next middleware function in the app. The next() function is not a part of the Node.js or Express API, but is the third argument that is passed to the middleware function. The next() function could be named anything, but by convention it is always named “next”. To avoid confusion, always use this convention.

    To load the middleware function, call app.use(), specifying the middleware function. For example, the following code loads the myLogger middleware function before the route to the root path (/).

    var express = require('express')
    var app = express()
    
    var myLogger = function (req, res, next) {
      console.log('LOGGED')
      next()
    }
    
    app.use(myLogger)
    
    app.get('/', function (req, res) {
      res.send('Hello World!')
    })
    
    app.listen(3000)
    

    Every time the app receives a request, it prints the message “LOGGED” to the terminal.

    The order of middleware loading is important: middleware functions that are loaded first are also executed first.

    If myLogger is loaded after the route to the root path, the request never reaches it and the app doesn’t print “LOGGED”, because the route handler of the root path terminates the request-response cycle.

    The middleware function myLogger simply prints a message, then passes on the request to the next middleware function in the stack by calling the next() function.


    1. This post will only contain myLogger middleware, for further post you could go to the original expressjs guide here.

    0 讨论(0)
提交回复
热议问题