Get data from grunt-contrib-connect request object

720 views Asked by At

So this is probably a very simple question, but I've been Googling around for over an hour and haven't been able to find anything. I also just tried printing out the request object, and I don't see anything useful.

How do I get the data or body of a client request within a grunt-contrib-connect middleware definition?

connect: {
  main: {
    options: {
      hostname: "0.0.0.0",
      port: 8080,
      /**
       *  These are the mocked out backends for various endpoints
       */
      middleware: function(connect, options, middlewares) {
        middlewares.unshift(function(req, res, next) {
          if (req.url !== '/v1/accounts/_findEmail') {
            return next();
          }

          // ********
          // How do I get the data content of the request?
          var data = req.data; // Is undefined
          // ********

          if (data && data.email === '[email protected]') {
            res.writeHead(200, {"Content-Type": "application/json"});
            res.write(JSON.stringify({email:"found"}));
          } else {
            res.writeHead(404, {"Content-Type": "application/json"});
            res.write(JSON.stringify({email:"not found"}));
          }

          res.end();
        });

        return middlewares;
      }

    }
  }
}
2

There are 2 answers

1
static416 On BEST ANSWER

So it turns out there are a couple things needed to make this work.

As stated here, connect is basically just wrapping NodeJS in this case, which I should have guessed. So that request object is actually http.ServerRequest, and should be used the same way.

So in place of var data = req.data; I can add a callback like req.on('data', function (data) { //do stuff }); and see the data that way.

In addition to that, before I read the data, I had to add req.setEncoding('utf8'); in order for it to come out as a string rather than a hex array.

So the final solution looks like:

connect: {
  main: {
    options: {
      hostname: "0.0.0.0",
      port: 8080,
      /**
       *  These are the mocked out backends for various endpoints
       */
      middleware: function(connect, options, middlewares) {
        middlewares.unshift(function(req, res, next) {
          if (req.url !== '/v1/accounts/_findEmail') {
            return next();
          }

          req.setEncoding('utf8');
          req.on('data', function (rawData) {
            var data = JSON.parse(rawData);

            if (data && data.email && data.email === '[email protected]') {
              res.writeHead(200, {"Content-Type": "application/json"});
              res.write(JSON.stringify({email:"found"}));
            } else {
              res.writeHead(404, {"Content-Type": "application/json"});
              res.write(JSON.stringify({email:"not found"}));
            }

            res.end();
          });
        });

        return middlewares;
      }

    }
  }
}
0
Tobi On

I couldn't explain it, but the solution by @static416 didn't work for me any longer. So I came up with a new one:

First install npm package body-parser and import it. Second, add this to your middleware:

module.exports = function(grunt) {
    var bodyParser = require('body-parser');
    ...
}

Now you are able to access the data by using req.body inside your middleware.

middleware: function(connect, options, middlewares) {
          // inject a custom middleware into the array of default 
          middlewares.unshift(
              bodyParser.urlencoded({extended: true}),
              bodyParser.json(),
              function(req, res, next){
                // use data from post request
                console.log(req.body);
                next();
              }, ...
          )
}, ...