svnm
svnm

Reputation: 24398

simple node.js example in aws lambda

I am trying to send a simple request with aws lambda.

My module structure is as follows:

mylambda
|-- index.js
|-- node_modules
|   |-- request

I zip the file up and it is uploaded to lambda.

Then I invoke it, and it returns the following error. "errorMessage": "Cannot find module 'index'"

Here is the contents of the index.js file

var request = require('request');

exports.handler = function(event, context) {

    var headers = { 'User-Agent': 'Super Agent/0.0.1', 'Content-Type': 'application/x-www-form-urlencoded' }

    // Configure the request
    var options = {
        url: 'https://myendpoint',
        method: 'POST',
        headers: headers,
        form: {'payload': {"text":""} }
    }

    // Start the request
    request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log(body)
        }
    })

    console.log('value1 =', event.key1);
    context.succeed(event.key1);  // Echo back the first key value
};

Any help is appreciated, Thanks

Upvotes: 9

Views: 8928

Answers (3)

Anurag Sindhu
Anurag Sindhu

Reputation: 25

Task: Write an aws lamda function:

How I have see us doing:

  1. We write code in aws editor and run that

  2. Not running as expected, put a lot of consoles there(because we can't debug our code)

  3. Wait for some seconds then see the consoles in another window, keep changing the windows until we resolve our problem

    4.changing the windows takes a lot of time and effort.

why can't we?

  1. write the code in our server (not aws editor) and then send that code to aws.

Yes, we can.

  1. new Function (https://davidwalsh.name/new-function) Blessing in disguise concept.

Sample code:

let fs = require('fs');
const aws = require("aws-sdk");
const s3 = new aws.S3(),
    async = require('async');
aws.config = {
    "accessKeyId": "xyz",
    "secretAccessKey": "xyz",
    "region": "us-east-1"
};
fs.readFile('path to your code file', 'utf-8', async (err, code) => {
    if (err) return res.status(500).send({ err });
    async function uploadToS3(docs) { (only this function has to go into aws editor)
        let func = new Function('docs', "aws", "s3", 'async', `${code}`);
        return func(docs, aws, s3, async); 
    }
    let resp = await uploa`enter code here`dToS3(req.files.docs);(this line will call aws lambda function from our server)
    return res.send({ resp });
});

Code which I have written in my file:

docs = Array.isArray(docs) ? docs : [docs]
let funArray = [];
docs.forEach((value) => {
    funArray.push(function (callback) {
        s3.upload({
            Bucket: "xxx",
            Body: value.data,
            Key: "anurag" + "/" + new Date(),
            ContentType: value.mimetype
        }, function (err, res) {
            if (err) {
                return callback(err, null);
            }
            return callback(null, res);
        });
    });
});
return new Promise((resolve, reject) => {
    async.parallel(funArray, (err, data) => {
        resolve(data);
    });
});

Benefit:

  1. As the whole code will be written in our familiar IDE, it will be easy to debug.
  2. Only two lines have to go into aws editor (isn't it easy).
  3. quite easy to modify/update the code(as the code will in our repo, we may not even have to go to aws editor).
  4. yes we can other third parties libraries, but the above thing is written in pure JavaScript, no third party library is utilized there.
  5. Also, here you don't have to deploy your code.
  6. Sometimes our libraries total size increased to 5 MB and AWS lambda editor stop supporting it. It will resolve this problem as well, now we will send only the required function from a library, not the whole library on an average an async library contains around 100s of functions, but we use 1-2 functions. So, now we will send only the function which we are going to use.

Note:

  1. I searched this a lot but nowhere found this kind of thing.
  2. The above piece of code will upload docs to the s3 bucket.

Upvotes: 1

Vasanth Umapathy
Vasanth Umapathy

Reputation: 1741

You have to zip and upload subfolders only, not a root folder. You have to zip following folders as per your example, then upload:

|-- index.js
|-- node_modules
    |-- request

Upvotes: 3

svnm
svnm

Reputation: 24398

All working now, I had to increase the Timeout(s) seconds in advanced settings, as it was taking longer than 3 seconds.

Also I had to ensure my node modules were correctly installed. I had messed up the request module when trying to figure out what was wrong.

To reinstall the module, I deleted then re-installed request.

  • deleted node_modules
  • npm init
  • added the dependancies "request" : "*" in the package.json,
  • npm install. Compressed the zip and uploaded, all working now. :)

Upvotes: 7

Related Questions