Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a Nodejs app how do I make an HTTP client request inside an Express method

When a browser or curl client calls my node express app, I want to fetch JSON data from an external website and return it, however despite seeing the nested http call return the JSON data back to my express server I'm battling to get the JSON to return to the calling browser - how do I do this?

Here is the current test app code with curl response:

var http = require('http');
var app = require('express')();

app.get('/', function (req, res) {

  var str = '';

  var options = {
    host: 'jsonplaceholder.typicode.com',
    path: '/posts/1'
  };

  callback = function(response) {
    response.on('data', function (chunk) {
      str += chunk;
    });

    response.on('end', function () {
      console.log(str);
    });
  }

  var req = http.request(options, callback);

  res.send(str);
  req.end();
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

Here is the result of CURL localhost:3000 (no body data returned): enter image description here

The server side console log's show the http request data has been received: enter image description here

All suggestions/pointers appreciated!

like image 454
Joelster Avatar asked Jun 04 '16 15:06

Joelster


2 Answers

Just as an alternative (the answer provided by m-a-r-c-e-l-i-n-o will work just fine), you can shorten your code (and save a bit of memory) by using the streams provided by both Express and http.request(), like this:

app.get('/', function(req, res) {
  http.request('http://jsonplaceholder.typicode.com/posts/1', function(response) {
    response.pipe(res);
  }).on('error', function(e) {
    res.sendStatus(500);
  }).end();
});
like image 110
robertklep Avatar answered Nov 11 '22 07:11

robertklep


It appears that you need to wait for the nested response to come back before sending out the actual response, like so:

app.get('/', function (req, res) {

  var str = '';

  var options = {
    host: 'jsonplaceholder.typicode.com',
    path: '/posts/1'
  };

  var callback = function(response) {
    response.on('data', function (chunk) {
      str += chunk;
    });

    response.on('end', function () {
      console.log(str);
      res.send(str); // SEND ACTUAL RESPONSE HERE
    });
  }

  var req = http.request(options, callback);
  req.end();

});

Otherwise, you are sending str right away and it's empty, thus why you can't see it.

like image 29
m-a-r-c-e-l-i-n-o Avatar answered Nov 11 '22 07:11

m-a-r-c-e-l-i-n-o