slogan
slogan

Reputation: 61

middleware after all route in nodejs

I want to have a middleware like Express log request summary end of each route =>

[POST] /books/commentpart 200 1435.472 ms - 35

I want to log more data in end of each request. But I do not know how to write middleware like this. I have tried a middleware function after all route but it not worked. In each router, I also pass next() call.


app.use(responseTime());
//router
app

  .use(users(app, db))  
  .use(dataLogs(app, db))  
  .use(category(app, db));

//log middleware
app.use(function(req, res, next) {   
    var data = {};  
    var method = req.method;
    if(method == 'GET'){
      data = req.query;
    } else {
      data = req.body;
    }   
    var resTime = res.getHeader('X-Response-Time');    
    log.debug(' [ ' + iduser + ' ] - ' + req.route.path +  ' - ' + resTime + ' : ' + JSON.stringify(data));
});

module.exports = app;

Upvotes: 5

Views: 4632

Answers (4)

Dumitru Bereghici
Dumitru Bereghici

Reputation: 11

Consider using async / await

const lastMiddleware = async (req, res, next) => {
    // Allow the route handler to run first and wait for it to be completed
    await next();

    // Do work
}

Upvotes: 0

Aidin
Aidin

Reputation: 29927

So, middlewares, when registered (using app.use, app.all, or etc.) are a queue of rules that apply to incoming requests. Note that this registration happens at the server-start time and is a part of the server itself, not requests.

Once it's all set up and the server is running, any hop (step in the queue, a.k.a middleware) after the first one is called only if the previous hop has called next() explicitly. In other words, if you put a app.use((req, res, next) => {}); at the beginning of all the middlewares, the server is gonna do absolutely nothing! -- this middleware is just swallowing any incoming request and not calling next().

Problem

Now the problem is, how can you register a middleware that:

  1. Applies to all rules, AND
  2. Runs after all the other middlewares

Satisfying the second requirement is not easy. Because as we mentioned above the last hop in this rules queue runs only when all the previous ones have gracefully called next() one after another. And sometimes it doesn't happen for various reasons, including simply forgetting to call next()! And it's hard to enforce people to do that.

Solution

I need to mention what @robertklep said in a comment above bolder. It's using on-finished on res! https://github.com/jshttp/on-finished

Example:

// have this before all the other middlewares
app.use((req, res) => {
    console.log("I'll be the first line executed, almost ever!");
    onFinished(res, (err) => {
        console.log("and I'll be the last one, knowing response"
                    + " code which is already sent is: " + res.statusCode);
    });
};

What this does is, actually listening on when the response is finished (you can alternatively use on-headers). So it's a whole new dimension of doing a job on express, prependicular to the existing middlewares queue mechanism. Just be careful and enjoy! ;)

Upvotes: 2

slogan
slogan

Reputation: 61

Finally it worked. Actually, in some routes, i forgot pass next() in the end of each router.

Now i do another method, utilizing responseTime function and it works perfectly without add next() to all every routes. Thanks all!

app.use(responseTime(function (req, res, time) {
  var data = {};  
    var method = req.method;
    if(method == 'GET'){
      data = req.query;
    } else {
      data = req.body;
    }
   log.info(method, iduser, req.path, ' - ', Math.round(time), 'ms', ' : ', JSON.stringify(data));
}))

Upvotes: 0

Ariel Henryson
Ariel Henryson

Reputation: 1346

middleware is just a function that do something and then pass the request to the next function using "next()". So if you really want to do that you need to catch all of your routes in the same route something like this

app.all('*', (req, res) => {
      // do something before

      // your async code here 

      // do something after
});

Upvotes: 0

Related Questions