0

_

MY CHALLENGE:

I would like to access a third party Rest API from within my Lambda function. (e.g."http://www.mocky.io/v2/5c62a4523000004a00019907").

This will provide back a JSON file which I will then use for data extraction

_

MY CURRENT CODE:

var http = require('http');

exports.handler = function(event, context, callback) {
    console.log('start request to Mocky');

    http.get('http://www.mocky.io/v2/5c62a4523000004a00019907', function(res) {
            console.log(res);

        })
        .on('error', function(e) {

            console.log("Got error: " + e.message);
        });
};

This does not throw an error but also does not seem to provide back the JSON

_

MY OPEN QUESTIONS:

1) How can I extract the JSON so that I can work on it

2) I will probably need to also send through an Authentification in the request header (Bearer) in the future. Will this also be possible with this method?

2 Answers 2

1

The problem is likely that your lambda function is exiting before logging the response.

We use Authorization headers all the time to call our lambdas. The issue of if you can use one to call the third party API is up to them, not you, so check the documentation.

Since your HTTP call is executed asynchronously, the execution of the lambda continues while that call is being resolved. Since there are no more commands in the lambda, it exits before your response returns and can be logged.

EDIT: the http.get module is difficult to use cleanly with async/await. I usually use superagent, axios, or request for that reason, or even node-fetch. I'll use request in my answer. If you must use the native module, then see EG this answer. Otherwise, npm install request request-promise and use my answer below.

The scheme that many people use these days for this kind of call uses async/await, for example (Requires Node 8+):

var request = require('request-promise')

exports.handler = async function(event, context, callback) {
    console.log('start request to Mocky');
    try {
        const res = await request.get('http://www.mocky.io/v2/5c62a4523000004a00019907')
        console.log(res)
        callback(null, { statusCode: 200, body: JSON.stringify(res) })
    }
    catch(err) {
        console.error(err.message)
        callback('Got error ' + err.message)
    }
};

The async/await version is much easier to follow IMO.

Everything inside an async function that is marked with await with be resolved before the execution continues. There are lots of articles about this around, try this one.

Sign up to request clarification or add additional context in comments.

7 Comments

Dear Matt, thank you so much for your help! FOR THE FIRST EXAMPLE: At first the process exited before completing the request. I then added "async" and it run successful. Where would I put a "console.log" statement to track if I actually receive any input from the API? FOR THE SECOND EXAMPLE: I first received an error for the catch statement. I then added another "}" after the try statement to complete this. However when I then try to run the program I get an error saying that it cannot find the "promisify" module
Put the console logs in the flow before you invoke the callbacks in either example, and that should work. You need Node 8+ to use promisify, and 7.6 or better to use async/await. Lambda accepts 8.10 these days, so upgrade if you can. I've edited my answer to include this additional information.
I'm on Node.js 8.10 and still get an error: ### Response: { "errorMessage": "Cannot find module 'promisify'", "errorType": "Error", "stackTrace": [ "Function.Module._load (module.js:474:25)", "Module.require (module.js:596:17)", "require (internal/module.js:11:18)", "Object.<anonymous> (/var/task/index.js:2:17)", "Module._compile (module.js:652:30)", "Object.Module._extensions..js (module.js:663:10)", "Module.load (module.js:565:32)", "tryModuleLoad (module.js:505:12)", "Function.Module._load (module.js:497:3)" ] } ###
Dear Matt, thank you again for your help. I have changed to the Typicode API ("jsonplaceholder.typicode.com/posts") just to make sure that there is no failure on the API end. I have changed the "http" parts into "https". However. I now get the code to work but get an error response of "undefined". Any ideas?
@Geole I forgot that the native http.get returns a stream. I never use it in practice because the syntax is more convoluted. I've simplified my answer to show how to make this request with request-promise.
|
0

There are a lot of guys having an equal problem already solved... Look at that or that

2 Comments

Dear Ore, thank you for your answer. I'm less struggling with the aysnchronous call as more with the ability to actually connect to the API and retrieve the data
Oh, i must have overlooked that. However, i strongly recommend you to listen to Matt Morgen, especially about the Serverless framework which takes away much of the struggle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.