简体   繁体   中英

How to use Nodejs "request" work aysn in AWS Lambda?

When I'm trying to use "request" to access external API and get back the response in AWS Lambda, I don't know how to properly put my "return" code to return the response.

NodeJs 8.10

var request = require('request');

module.exports.sendcode = async (event) => {

  let options = {
    url: 'https://api.netease.im/sms/sendcode.action?' + content, 
    method: 'POST'
  };

  return await request(options, function (error, response, body) {
    console.log(body); 
    return {
      statusCode: 200,
      body: JSON.stringify({
        message: body,
        input: event,
      }),
    };
  });
};

When I run this code in serverless framework, I got a null response, there is nothing in the body, actually it should have at least the "input" attribute.

But console.log already logs the actual response from API.

It looks like my "return" code is not executed at all. (If I remove async and await, then the program hangs until timeout)

Can anyone help how to modify this code to make it work?

Request does not use promises, so your await keyword is doing nothing. If you want to use promises with request, you need to find a library that supports promises, as noted here: https://www.npmjs.com/package/request#promises--asyncawait A popular option is https://github.com/request/request-promise-native

However, it is a simple matter to simply wrap a request in a promise, so that you don't need to use another dependency

var request = require('request');

const requestHandler = (options) => new Promise((resolve, reject) => {
  request(options, (error, response, body) => {
    if (error) {
      console.error(error);
      reject(error);
    } else {
      console.log(response, body);
      resolve({ response, body });
    }
  });
});

module.exports.sendcode = async (event) => {

  let options = {
    url: 'https://api.netease.im/sms/sendcode.action?' + content, 
    method: 'POST'
  };
  const { response, body } =  await requestHandler(options);
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: body,
      input: event,
    })
  }
};

Instead of writing your own promise wrapper, maybe request-promise pacakge with promise wrapper on top of request by the same authors, would be of interest to you.

const rp = require('request-promise')

module.exports.sendcode = async (event) => {

  let options = {
    url: 'https://api.netease.im/sms/sendcode.action?' + content, 
    method: 'POST'
  };

  const body =  await rp(options)
  console.log(body);
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: body,
      input: event,
    }),
  };
};

If you want full response you've to simply set resolveWithFullResponse to true

let options = {
  url: 'https://api.netease.im/sms/sendcode.action?' + content, 
  method: 'POST',
  resolveWithFullResponse: true
};

// now response contains full respose
const response =  await rp(options)
// response.body
// response.statusCode

Use Async/Await with promises. You cannot use Async-Await syntax with callback. Either you must write a promise wrapper for your 'request'callback or you can use request-promise module which is already available.

I have already provided answer for similar problem which you can refer here. Undefined value after returning an array of values from a MySQL query in a different file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM