0

I am trying to write a simple AWS Lambda function to retrieve data from an external public API. I have copied and pasted code from all over the internet without any luck.

I have stripped down the code to be a simple as possible to keep it simple. The public API is : https://swapi.co/api/people/1/

How can I get the data back from the public API?

const https = require('https');

exports.handler = async (event) => {

    var options = {
      method: 'GET',
      host: 'https://swapi.co/api/people/1/',

    };

     console.log('options', options);

     const req = https.request(options, (res) => {
         console.log('statusCode: ${res.statusCode}')
         console.log(JSON.stringify(res))
     });


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

The log file within the AWS editor shows:

START RequestId: 3ba3f23a-11c2-40af-b9e7-0258a6531728 Version: $LATEST
2019-05-27T16:17:44.839Z    3ba3f23a-11c2-40af-b9e7-0258a6531728    INFO    options { method: 'GET', host: 'https://swapi.co/api/people/1/' }
END RequestId: 3ba3f23a-11c2-40af-b9e7-0258a6531728
REPORT RequestId: 3ba3f23a-11c2-40af-b9e7-0258a6531728  Duration: 305.90 ms Billed Duration: 400 ms     Memory Size: 128 MB Max Memory Used: 26 MB  
Ravi Ram
  • 24,078
  • 21
  • 82
  • 113

2 Answers2

0

There were a few issues with your code:

The callback function passed into the handler triggers the end of the execution, or is called for you when your code exits if you don't call it yourself. I'm not entirely sure how this interacts with asynchronous javascript code, but it might have been causing your code to exit early that you didn't call it anywhere.

You're using an async method, which is good practice, but your rest call isn't using it, but a callback approach. This can be converted into an async call, as I show below, which makes the code a bit easier to understand.

I think the biggest problem, though, is that your options are wrong. You don't need https at the start of the host (because it already knows the scheme) and the path can't be in the host. I didn't spot this initially.

This is working for me, although you can't call JSON.stringify on the entire response, because it's a complex object, not just a model.

const https = require('https');

exports.handler = async (event, context, callback) => {
    var options = {
        method: 'GET',
        host: 'swapi.co',
        path: '/api/people/1/',
    };
    await new Promise((resolve, reject) => {
        let request = https.request(options, response => {
            try {
                // do whatever
            } finally {
                resolve();
            }
        });
        request.on('error', (e) => reject(e));
        request.end();
    });
    callback();
};
gandaliter
  • 9,863
  • 1
  • 16
  • 23
  • This code is not working. Can you be more detailed? – Ravi Ram May 27 '19 at 19:57
  • thanks, I am not getting an error now. However, I am not getting the JSON back from the API. So we are closer. – Ravi Ram May 27 '19 at 21:45
  • It looks like https.request is quite a low-level call (https://nodejs.org/api/https.html#https_https_request_options_callback) - you have to call `request.on('data', d => {})` to get the actual contents. You should be able to test that bit of your code outside of AWS Lambda though, as it's just node at that point. – gandaliter May 27 '19 at 21:56
  • I am still not able to get back the json data. Is there a better way of getting data from an API using AWS Lambda? (using AWS online code editor)? – Ravi Ram May 28 '19 at 13:48
0

The below code is working

const http = require("https");

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

  var options = {
    "method": "GET",
    "hostname": "app.casejacket.com",
    "port": null,
    "path": "/api/",
    "headers": {
      "cache-control": "no-cache",
      "Content-Type": "application/json"
    }
  };

  await new Promise((resolve, reject) => {
    console.log('Promise.. ');

    var req = http.request(options, function (res) {
      var chunks = [];

      res.on("data", function (chunk) {
        chunks.push(chunk);
      });

      res.on("end", function () {
        var body = Buffer.concat(chunks);
        let result = JSON.parse(body.toString());
        console.log(body.toString());
        resolve(body.toString());
        callback(null, result)
      });
    });

    req.end();
  });

  callback();

};
Ravi Ram
  • 24,078
  • 21
  • 82
  • 113