Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

README.md

Example Lambda App: Notepad

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).

lambda-notes

Pre-requisites

This mini-tutorial expects you to have:

Everything else will be covered step-by-step!

How?

This step-by-step guide will take you from zero to Lambda-based Note taking app in the next 15 minutes.

Step 1: Create The DynamoDB Table to Hold your Notes

We need a place to store our Notes (data). DynamoDB is a great place for it.

1. Login to AWS Console and Select DynamoDB from the menu:

lambda-locate-dynamo-db

2. In the DynamoDB view click "Create Table":

dynamodb-create-table

3. Create your DynamoDB Table:

Call your table "Notes" and give it a "Primary Key" called Id of type String. Then click the "Create" button:

dynamodb-table-notes

4. Create an "Item" (Record) in your Note Table:

dynamodb-create-item

From the "Tree/Text" selector, chose "Text":

dynamodb-select-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:

dynamo-db-showing-notes-item


Step 2: Give Lambda Permission to Access the DynamoDB Table

#### 1. From the AWS Console Select "Identity & Access Management"

lambda-identity

2. Select Roles and then "Create New Role":

create-new-role

#### 3. Set Role Name to APIGatewayLambdaDynamoDB and click "Next Step"

aws-set-role-name

4. Select "AWS Lambda" then click "Next Step":

select-lambda

5. Click to add an in-line Policy

aws-role-inline-policy

6. Click "Custom Policy" and then "Select":

aws-custom-policy

7. Call your Policy LogAndDynamoDBAccess and paste:

{
  "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:

dynamodb-resource-name


Step 3: Create your Lambda Function(s)

1. Create a Lambda Function that Gets a Notes Record from DynamoDB

From the AWS Console, select Lambda:

aws-menu-click-lambda

Then click "Create a Lambda function":

aws-create-lambda-function

When prompted to chose from a "Blueprint" click "Skip":

aws-lambda-select-blueprint

2. Name your Lambda function "GetNotes"

aws-lambda-getnotes-function-name-and-desc

3. Paste this code into the in-line editor

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);
};

4. Test your GetNotes Lambda Function

Confirm that your GetNotes Lambda function can access DynamoDB by running a "Test":
(click the "Test" button to run your function)

aws-lambda-service-test

In the logs below your Lambda code, you should expect to see:

{
  "Id": "1",
  "notes": "Hello World!"
}

5. Create Your Second Lambda Function to Save Notes to DynamoDB

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);
};

aws-lambda-setnotes-function

Leave all other ("Advanced") settings as default and click "Next"

aws-lambda-click-next

Review the function and click "Create Function":

aws-lambda-create-function

You should expect to see a message confirming your Lambda Function was created:

aws-lambda-congrats

6. Test the SaveNotes Lambda Function

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:

aws-savenotes-test-data

You should expect to see the following:

aws-savenotes-test-output

Now if you go back and Test the GetNotes function, you should expect to see the following output:

aws-getnotes-updated-test-output


Step 4: Expose your Lambda Functions through AWS API Gateway

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"

aws-lambda-create-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":

aws-lambda-add-api-endpoint-getnotes

You should see a confirmation message informing you that your API endpoint for function GetNotes has been added at a Specific URL.

lambda-api-endpoint-exposed

In the case of our example the URL is:
https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotes

Test Endpoint Using cURL

Try "curl-ing" the endpoint:

curl -v https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotes

You should see:

aws-lambda-curl-getnotes-endpoint-

Repeat the previous steps for the /SaveNotes Lambda Function

  • 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 /SaveNotes endpoint with POST data

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/SaveNotes

Running 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/GetNotes

Which should return:

{"Id":"1","notes":"Updated Notes!"}

Step 5. Enable CORS for the Endpoints

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:

aws-lambda-cors-error

Official CORS Docs for Lambda: https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html#how-to-cors-console

1. In your API Gateway click "Enable CORS"

Select the resource/method you want to enable CORS for, click "Enable CORS" button.

aws-api-gateway-enable-cors

2. Click: "Enable CORS and replace existing CORS headers"

Leave all the default values as they are. (you can always come back and change them later...)

aws-awpi-gateway-enable-cors-and-replace

3. Click "Yes, Replace Existing Values"

In the "modal" window that pops up, click the button labeled "Yes, Replace Existing Values":

aws-api-gateway-replace-exisiting-values

4. Confirmation CORS ENabled

You should see a confirmation message similar to this:

aws-api-gateway-cors-enabled


Step 6. Deploy your API!

1. Click on "Deploy API"

aws-api-gateway-deploy-api

2. Configure the API to "prod"

aws-api-gateway-deploy-prod

3. Confirm your Configuration > "Save Changes"

aws-api-gateway-deploy-confirm

Copy the Invoke URL displayed as you will use it in the next two steps.

4. Test it in your Terminal with cURL

To confirm that the CORS (``) header is being set for the endpoint,

curl -v https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotes

You should expect to see output similar to the following:

aws-api-gateway-curl-confims-access-control-header

The important line is: < Access-Control-Allow-Origin: * which confirms that we can access the API endpoint from any origin.


Step 7. Update the baseURL in notes.html

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';

Step 8: Upload your "Client" notes.html App to S3

1. From your AWS Console Select S3:

lambda-01-dashboard-select-s3

2. Open your "Bucket" and upload the notes.html file into the bucket.

(If you don't already have a "Bucket" on S3, create one now.)

lambda-s3-upload-file

s3-select-file

3. Now make the notes.html file Public:

s3-make-public

4. Once you have made the file public, open it in your browser:

s3-open-the-file

You should expect to see something like this:

s3-make-notes

Try it!

Background Reading

Performance?

try:

For the API Gateway Endpoint

ab -n 10000 -c 1000 https://r09u5uw11g.execute-api.eu-west-1.amazonaws.com/prod/GetNotes

For the notes "app":

ab -n 10000 -c 1000 https://s3-eu-west-1.amazonaws.com/dwyl/notes.html