How to make expressjs support batch request like facebook

I have a set of routes with different methods. I want to make the expressjs to support batch request which is very similar to facebook, Facebook Batch Request. Does anybody know how to do it? And I dont want to make 3 loopback connections for handling the batch request.

If you don't want to make loopback connections, then the simplest solution is to manually call your server with fake requests.

You'll have to reimplement IncomingMessage. You should also use Async#map to wait until all requests are processed.

Here's the basic idea:

// You'll probably have more work to do to reimplement http basic API.
function FakeRequest(request) {
  this.url = '/' + request.relative_url;
  this.method = request.method;
  this.headers = request.headers;
}

function FakeResponse() {
  Stream.call(this);

  this.statusCode = null;
  this.body = '';
}

FakeResponse.prototype.write = function (chunk) {
  this.body += chunk.toString('utf8');

  return true;
};

util.inherits(FakeResponse, Stream);

app.post('/', function (req, res) {
  var requests = JSON.parse(req.body.batch);

  async.map(requests, function (request, done) {
    var fakeReq = new FakeRequest(request),
        fakeRes = new FakeResponse();

    // call Express' middleware manually
    app(fakeReq, fakeRes);

    // this will trigger when the response is ready.
    fakeRes.once('end', function () {
      // don't leak listeners
      fakeRes.removeAllListeners();
      done(null, fakeRes);
    });

    fakeRes.once('error', function (err) {
      fakeRes.removeAllListeners();
      done(err);
    });
  }, function (err, responses) {
    if (err)
      return res.send(err);

    res.send(responses);
  });
});

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

UPDATE

I'm actually not sure what you mean by loopback, but you have 2 options:

  • Open an HTTP connection for each request in the batch, which is easier to implement but slower.

  • The solution I outlined above: call the Express middleware directly without opening HTTP requests.

I was under the impression that you didn't want the first solution. However, that's what I would try first, even if it's slower:

  • Easier to spread your batch connections across multiple instances when you scale.
  • You won't bypass any load throttling mechanism you might have (that prevent a single Express instance from processing too many requests simultaneously).

Be sure to disable the HTTP Agent though.