alwaysAStudent
alwaysAStudent

Reputation: 2274

Fetch Http Response NodeJS

Trying to execute a AWS Lambda in NodeJS (newbie to nodeJs) in which I make a http request. At the end of Lambda execution, I wish to return response code and response message of http request.

Making the http request call:

var executeRequest = function(request, callback) {

const req = https.request(request, (res) => {

  console.log('statusCode:', res.statusCode);
  console.log('headers:', res.headers);

  res.on('data', (d) => {
     process.stdout.write(d);
  });
  callback(res);
});

req.on('error', (e) => {
  console.error(e);
});

req.end(request.body);

};

Lambda Code:

    exports.handler = (event, context, callback) => {

    // Formulate request 

    var result = executeRequest(request, function(response) {
         console.log("Response Code: ", response.statusCode);
         console.log("Response Message: ", response.statusMessage);
         // Successfully able to print the response above

        return response;
     });
     console.log("Result Response Code: ", result);
     console.log("Result Response Message: ", result);
     } 

I wish to return the response.statusCode and response.statusMessage as response from Lambda

return{
    statusCode: <the code>,
    body: <the message>,
};

However, the result is populated as undefined. How to extract the required response parameter so they can be returned correctly?

** Edit: ** Snippet after changes suggested: Code using Promise:

var executeRequest = function(request, callback) {

    return new Promise((resolve, reject) => {
        https.request(request, function(res) {
            if(res.statusCode==200 || res.statusCode==404) {
                resolve(res);
            }
            else {
                console.error(res);
                reject(res.statusCode);
            }
        }).end(request.body || '');
    });
};


exports.handler = (event, context, callback) => {

    // Formulate request 

    var value = executeRequest(request).then(function(result) {
  console.log("Result ", result);
  const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!') }; 
  return response;
 });

    console.log(value);
}

Upvotes: 2

Views: 742

Answers (3)

Hans-Eric Lippke
Hans-Eric Lippke

Reputation: 248

Try something like this.

exports.handler = function( event, context, callback ) { 
 //this is to allow function to return as soon as result is shown
 context.callbackWaitsForEmptyEventLoop = false;
 var request = ...//I expect request is a predefined value or define the request here.

 executeRequest(request).then( function( result ) { 


  //keep all console log before return.
  console.log("Result ", result);

  const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!') }; 

  callback(null, response);
  return;
 });
}
function executeRequest(request){
   return new Promise( ( resolve, reject ) => {

    https.request(request, function(res) {

     if(res.statusCode==200 || res.statusCode==404) {
        resolve(res);
     }else {
        console.error(res);
        reject(res.statusCode);
        return;
     }
    }).end(request.body || '');
  });
}

Upvotes: 1

Matus Dubrava
Matus Dubrava

Reputation: 14502

Problem is that your executeRequest is asynchronous and your lambda doesn't know about that so it will simply return right away.

Instead of returning the response, pass it to callback as the second argument (first is error object)

callback(null, response)

This part is executed and without waiting for the executeRequest response, the rest of the code is executed

var result = executeRequest(request, function(response) {
     console.log("Response Code: ", response.statusCode);
     console.log("Response Message: ", response.statusMessage);
     // Successfully able to print the response above

    return response;
 });

So at this point

console.log("Result Response Code: ", result);
console.log("Result Response Message: ", result);

The result is still empty.

So you should instead do something like this.

var result = executeRequest(request, function(response) {
     console.log("Response Code: ", response.statusCode);
     console.log("Response Message: ", response.statusMessage);
     // Successfully able to print the response above

     callback(null, response);
 });

Upvotes: 3

Kannaiyan
Kannaiyan

Reputation: 13055

Change your Lambda code to the following,

exports.handler = (event, context, callback) => {

    // Formulate request 

    var result = executeRequest(request, function(response) {
         console.log("Response Code: ", response.statusCode);
         console.log("Response Message: ", response.statusMessage);
         // Successfully able to print the response above

        callback(null, response);
     });

     } 

Hope it helps.

Upvotes: 0

Related Questions