Deploy an AWS Lambda function to store data in DynamoDB using the Serverless Framework

Nik Graf
InstructorNik Graf
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 4 years ago

In order to store data into a DynamoDB table we first need to setup the permissions for the Lambda function to have write access. Further we can use the DocumentClient API shipping with AWS to write the data coming from a request to the DynamoDB table.

Instructor: [00:00] Using a lambda function, we want to write data to a DynamoDB table. We remove our Hello World, including its handler, and create a new one called createTodo. We provide the handler and the HTTP event.

[00:14] There is one thing missing, though, in this configuration to make it work. By default, a lambda function is not allowed to interact with the table. We need to give our lambda functions access. To do so, we need to use an identity and access management, short IM rule.

[00:33] Under the hood, the serverless framework already attaches an IM rule. Using the IM rule statement syntax, we can extend the permissions for this specific IM rule. We allow that our functions can execute the action DynamoDB putItem on our table resource.

[00:51] The resource has to be provided as an Amazon resource name, or short ARN. For DynamoDB, it starts of ARN, AWS, then the service, the region, the account ID, resource time, and the resource. While in examples you'll often see an asterisk used as a wildcard, I recommend you to lock down the permissions as much as possible for a tighter security.

[01:19] Now, we are missing our handler. Let's create the file, create.js. In there, [inaudible] our function. Here, we can pass the provided body as JSON, and return a response.

[01:44] In order to interact with DynamoDB, we can import the AWS JavaScript SDK, and instantiate the document client. There is no need to install it, since the lambda [inaudible] of it. We create the parameters for DynamoDB put, containing table name, and the item we want to store.

[02:08] Then we invoke put on the client with these parameters. We use a wait to make sure the code doesn't proceed until the request finished successfully. In case of in failure, the function would arrow with a status code 500.

[02:23] In case we would want to have a custom error message, we could wrap it with a try-catch statement. There is one more thing we need to fix about this code, though. Storing every item with the same ID will not lead to the expected results.

[02:37] Let's use the UUID package from NPM to generate the new ID on every request. Therefore, we add a minimal package.json, and run npm install --save uuid to install the package. We then can import the module and use its UUID function.

[03:09] Now we've got everything in place and can deploy again. As mentioned in the previous lesson, the serverless framework creates a SIP. In this case, it will actually include the local node modules as well. Once deployed, we can use curl again, and create the to-do.

[03:38] We can check in the AWS console if our submission was successful. If we leave out the data part, the function will fail and return an error, as expected.

Daniel Uhl
Daniel Uhl
~ 6 years ago

Great so far!

You have a couple minor typos in your last Create.js in the transcript:

const AWS = require('aws-sdk');
const uuid = require('uuid/v4');

const client = new AWS.DynamoDB.documentClient();

module.exports.run = async (event) => {
  const data = JSON.parse(event.body);
  const params = {
    TableName: 'todos',
    Item: {
      id: uuid(),
      text: data.text,
      checked: false
    }
  };
};
Brain Imascono
Brain Imascono
~ 5 years ago

If you are using the cmd and single quotes are giving you problems, use double quotes and escape the quotes within the string: curl -X POST https://zm7tuyj33a.execute-api.us-east-1.amazonaws.com/dev/todos --data "{"text": "learn serverless"}"

Mark
Mark
~ 5 years ago

I was having issues with posting data with curl. I was getting "Internal Server error". After checking CloudWatch it turns out that the updated uuid package I was using, had changed its API

From https://www.npmjs.com/package/uuid

const { v4: uuidv4 } = require('uuid');
uuidv4(); // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed'

So I had to use uuidv4() for creating a todo id to make it work

Markdown supported.
Become a member to join the discussionEnroll Today