In this tutorial we are going to build a little app that allows us to take notes and save them to Amazon DynamoDB via an AWS Lambda Function (available from AWS API Gateway).
This mini-tutorial expects you to have:
- An Amazon Web Services (AWS) Account: https://aws.amazon.com/
- Basic Node.js/JavaScript Knowledge
Everything else will be covered step-by-step!
This step-by-step guide will take you from zero to Lambda-based Note taking app in the next 15 minutes.
We need a place to store our Notes (data). DynamoDB is a great place for it.
Call your table "Notes" and give it a "Primary Key" called Id of type String.
Then click the "Create" button:
From the "Tree/Text" selector, chose "Text":
Then paste this JSON in as the record and click the "Save" button:
{
"Id": "1",
"notes": "Hello World!"
}You should now have one item in your Notes table:
#### 1. From the AWS Console Select "Identity & Access Management"
#### 3. Set Role Name to APIGatewayLambdaDynamoDB and click "Next Step"
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AccessCloudwatchLogs",
"Action": ["logs:*"],
"Effect": "Allow",
"Resource": "arn:aws:logs:*:*:*"
},
{
"Sid": "PetsDynamoDBReadWrite",
"Effect": "Allow",
"Action": [
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem"
],
"Resource": ["arn:aws:dynamodb:eu-west-1:182294303866:table/Notes"]
}
]
}Note: your "Resource" value will be different. To locate yours, view the details of your DynamoDB Table:
From the AWS Console, select Lambda:
Then click "Create a Lambda function":
When prompted to chose from a "Blueprint" click "Skip":
var AWS = require('aws-sdk');
var DOC = require('dynamodb-doc');
var dynamo = new DOC.DynamoDB();
exports.handler = function(event, context) {
var cb = function(err, data) {
if(err) {
console.log('error on GetNotes: ',err);
context.done('Unable to retrieve notes', null);
} else {
if(data.Item && data.Item.notes) {
context.done(null, data.Item);
} else {
context.done(null, {});
}
}
};
dynamo.getItem({TableName:"Notes", Key:{Id:"1"}}, cb);
};Confirm that your GetNotes Lambda function can access DynamoDB by running a "Test":
(click the "Test" button to run your function)
In the logs below your Lambda code, you should expect to see:
{
"Id": "1",
"notes": "Hello World!"
}The steps are similar to the previous Lambda function you just created. Again, click "Skip" when asked if you want to use a "boilerplate" for your new function.
Then enter the following details:
- Name:
SaveNotes - Description:
Save ("Put") Notes to DynamoDB Notes Table - Runtime:
Node.js - Handler:
index.handler - Role:
APIGatewayLambdaDynamoDB
Then paste the following code:
var AWS = require('aws-sdk');
var DOC = require('dynamodb-doc');
var dynamo = new DOC.DynamoDB();
exports.handler = function(event, context) {
var item = { Id:"1",
notes: event.notes // notes passed in as PUT request body
};
var cb = function(err, data) {
if(err) {
console.log(err);
context.fail('unable to update notes at this time');
} else {
console.log(data);
context.done(null, data);
}
};
dynamo.putItem({TableName:"Notes", Item:item}, cb);
};Leave all other ("Advanced") settings as default and click "Next"
Review the function and click "Create Function":
You should expect to see a message confirming your Lambda Function was created:
Testing this Lambda function is similar to the previous one, the only difference is that you will be prompted to input some test event data.
Paste the following:
{
"Id": "1",
"notes": "These are my Lambda Notes!"
}And then click the "Save and Test" button:
You should expect to see the following:
Now if you go back and Test the GetNotes function, you should expect to
see the following output:
There are three ways to make your Lambda functions accessible to the outside world using the AWS API Gateway; we are going to use the "easy" way.
While viewing your GetNotes Lambda function, click on the
API endpoints tab and then click "Add API Endpoint"
Then configure your endpoint with the followin:
- API endpoint type:
API Gateway - API name:
LambdaMicroservice - Resource name:
/GetNotes - Method:
GET - Deployment stage:
prod - Security:
Open(expect to see a warning message)
Once you have entered/selected the data, click "Submit":
You should see a confirmation message informing you that
your API endpoint for function GetNotes has been added at a Specific URL.
In the case of our example the URL is:
https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotes
Try "curl-ing" the endpoint:
curl -v https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotesYou should see:
- API endpoint type:
API Gateway - API name:
LambdaMicroservice - Resource name:
/SaveNotes - Method:
POST - Deployment stage:
prod - Security:
Open(expect to see a warning message)
Once you have successfully created the endpoint, you can test it.
curl -v -H "Content-Type: application/json" -X POST -d '{"Id":"1","notes":"Updated Notes!"}' https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/SaveNotesRunning that command will return an empty Object as response.
We can confirm that the notes were updated by re-running the GetNotes
curl command:
curl https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotesWhich should return:
{"Id":"1","notes":"Updated Notes!"}Right now your API endpoints are accessible via cURL
or "Postman" but will be blocked by browser's "Same Origin Policy".
If you attempt to access the API Gateway endpoint via XMLHttpRequest ("Ajax") in the
browser you will see a No 'Access-Control-Allow-Origin' Error:
Official CORS Docs for Lambda: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html#how-to-cors-console
Select the resource/method you want to enable CORS for, click "Enable CORS" button.
Leave all the default values as they are. (you can always come back and change them later...)
In the "modal" window that pops up, click the button labeled "Yes, Replace Existing Values":
You should see a confirmation message similar to this:
Copy the Invoke URL displayed as you will use it in the next two steps.
To confirm that the CORS (``) header is being set for the endpoint,
curl -v https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotesYou should expect to see output similar to the following:
The important line is: < Access-Control-Allow-Origin: * which confirms
that we can access the API endpoint from any origin.
Open the notes.html file and scroll down to the JavaScript section where baseURL is defined.
Replace the value of baseURL with the API Gateway Invoke URL you used for your cURL request above.
e.g:
var baseURL = 'https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod';(If you don't already have a "Bucket" on S3, create one now.)
You should expect to see something like this:
Try it!
- Amazon API Gateway Tutorial by Auth0: https://auth0.com/docs/integrations/aws-api-gateway
- Measuring response time with cURL: https://stackoverflow.com/questions/18215389/how-do-i-measure-request-and-response-times-at-once-using-curl
try:
For the API Gateway Endpoint
ab -n 10000 -c 1000 https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotesFor the notes "app":
ab -n 10000 -c 1000 https://s3-eu-west-1.amazonaws.com/dwyl/notes.html











































