0
votes

As part of a Lambda training effort, I am attempting to write a simple application that triggers a Lambda function via API Gateway. That Lambda function then connects to DynamoDB via the AWS SDK and attempts to delete an existing table.

The Lambda function fires when I perform a POST against the API Gateway endpoint. I get a response back as {}, which means that result was never re-assigned beyond the initialized value. As far as I can tell the deleteTable method never fires. I never see either the console.log() or the console.error(), which exist inside the body of the callback.

Please find details below:

Setup

Lambda Function

  • Language: Node.Js 8.10
  • Triggers: API Gateway POST endpoint
  • Execution Role Rights:
    • Basic Microservice Template (Note: I've also attempting giving it explicit DynamoDB Full Access, and even Full Administrator; this didn't help anything.

Here's the code. I had something a lot more involved but trimmed it down to this when I couldn't get the delete to work:

exports.handler = async (event) => {
    var aws = require('aws-sdk');
    var dynamodb = new aws.DynamoDB();
    
    var params = {
        TableName: "StudyGuideSections"
    };
    
    var result = {};
    
    dynamodb.deleteTable(params, function(err, data) {
        console.log('Entering deleteTable callback...');
        
       if (err) {
           console.log(err, err.stack);
       } else {
           console.log(data);
           
           result = data;
       }
    });
    
    return {
        statusCode: 200,
        "headers": {
            "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(result)
    };
};

API Gateway

  • Authorization: None
  • Method: POST

Client-Side

  • Postman (For testing)
  • Simple web application executing $.post

I've looked at the CloudWatch and X-Ray logs and I don't ever see errors, nor do I see the console.log() attempts from inside the body of the deleteTable() call.

I'm all but pulling my hair out at this point as it has put a blocker on my training. Any help would be greatly appreciated.

Edit: For further clarification, I can change the return value's body to be something like "Hello World!" and I get that back as the response. Additionally, I can put a console.log('Attempting to delete table...") right before the deleteTable call; when I do that, I see it in CloudWatch. I just never see the logs from inside the deleteTable method.

1
Do you see any logs at all? Is your lambda even being called by the GW?AlexK
Yes, I see logs in CloudWatch. The logs simply show the start and end of the call. If I put a console.log before the deleteTable, I see the console.log message in CloudWatch. If I change the result body to be something like "Hello World!", I see that message in the Response from Postman. The function fires, it just never calls deleteTable for some reason.Brandon Avant
Hmm you seem to be missing => after the function call. This is what I mean : dynamodb.deleteTable(params, function(err, data) =>AlexK
Hmmm...I don't think you can use that syntax. I would have to do this dynamodb.deleteTable(params, (err, data) => {, which I just tried and it doesn't make a difference.Brandon Avant
Fair enough, my badAlexK

1 Answers

1
votes

I finally figured this out. Because I was utilizing Node.js 8.10, I needed to use the Promise structure instead of the Callback structure.

Edit:

As Kalev mentioned, the fact that I'm using an async function for the handler is what necessitated the use of the await and .promise() and not the fact that I was using Node.js 8.10, which still supports the callback structure.

For example, instead of what I was originally attempting, I needed to do something more like this:

var aws = require('aws-sdk');

exports.handler = async (event) => {
    var ddb = new aws.DynamoDB();

    aws.config.update({
      region: "us-east-1"
    });

    var params = {
        TableName: "StudyGuideSections"
    };

    var result = {}

    try
    {
        result = await ddb.deleteTable(params).promise();
    }
    catch(ex) {
        result = ex;
    }

    return {
        statusCode: 200,
        "headers": {
            "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(result)
    };
};

Make special note of the result = await ddb.deleteTable(params).promise(); as that's the part that I was messing up.