How create a serverless website using AWS Lambda, AWS S3, AWS API Gateway and AWS DynamoDB with node.js? Full Tutorial!

This post will show you how we can create a web site using AWS serverless architecture.

Architecture

The architecture would look something like below:

sl1
Basic Architecture of my Serverless Web Application

The services and technologies we will be using to build this application are:

  • AWS Lambda
    • AWS Lambda is a compute service that lets you run code without provisioning or managing servers.
  • AWS API Gateway
    • Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale.
  • AWS S3
    • AWS S3 is Object storage built to store and retrieve any amount of data from anywhere

  • AWS DynamoDB
  • AWS Route 53
    • For creating and registering a domain name for the web app.
  • AWS IAM
    • AWS IAM for creating users, roles and policies.
  • HTML, CSS and JQuery
    • These are the client side web frameworks
  • node.js 
    • node.js is the server side JavaScript framework.

About the Application

The application we are going to create consists of an html web page which consists of three input fields – employee id, first name, last name. it also has two buttons – Save Profile and View a profile.

2

Steps to create the web app on a AWS serverless architecture:

  1. Create a  basic html, css web page layout.
  2. Create a DynamoDB table with columns- id, empid, firstname, lastname
  3. Create IAM policy for lambda to gain access to DynamoDB database and other resources
  4. Create a Lambda function to GET data from dynamodb table
  5. Create a Lambda function to POST data into dynamodb table
  6. Create an API using API gateway
  7. Create a GET API function inside API gateway
  8. Create a POST API functin inside API gateway
  9. Create an S3 bucket
  10. Upload all the web files in the S3 bucket

Create a DynamoDB table with columns:empId, empFirstName, empLastName, empAge

Go to DynamoDb and click on Create table and fill the details as shown below:

dynamodb0dynamodb1

Then Click on Create item and fill test data as shown below:

dynamodb3

Your DynamoDB table would look like below:

dynamodb4

 

Creating Our Lambda Functions – GET and POST Employee Details

Go to AWS lambda service under compute section.

Lambda1

Click on create function

lambda2

Creating the getEmployeeProfile lambda function

Fill the details for you function and add a role(Create a new role if you do not have an existing one) as shown below and Click on Create function:

lambda3

You will see the screen as shown below that the Lambda function has been created successfully.

lambda4

index.js will be default node.js file, paste the following code as show in the file. The following code scans the DynamoDB file and displays all the table data.

We have used scan operation of DynamoDB table scan for node.js

Find the below code for getEmployeeProfile.js here on my Github

lambda5

Below that configure the Environment Variables: Add TABLE_NAME as show below. So that lambda code knows which table to for.

lambda6

Change the event handler name to index.getempprofile according to the source code as shown below via red arrow.

lambda7

before testing the Lambda function let us first configure the test event.

Click on the dropdown as shown below and click on Configure test event

lambda8

Add a test event, add an partition key i.e empId.

“empId”: “*” means get all rows of data. Save the event and the function.

lambda9

Click on Test. It will take a second or so to get the data from DynamoDB table.

The function execution is successful and shows the table data in JSON format as shown in below image.

lambda11

So our one lambda function is ready whose function is to get employee details from database.

Let us create a POST function to post data to the database:

Creating the addEmployeeProfile lambda function

Add the details as done before.

lambda12

Add the node.js code for adding employee details to database. Use the code as shown below:

we have used Put Item Operation of DynamoDB

Find the below code for getEmployeeProfile.js here on my Github

lambda13

Configure the test event for this function also.

lambda14

Test Run the function.

lambda15

As shown in the above pic, the function is successfully executed.

Now let us check DynamoDb table if it is updated or not.

lambda16

Yes, as you can see the table has been updated with new values which were passed from the test event of the lambda function.

Adding API Gateway as a trigger to Lambda function and Creating an API

Going further we have to create a RESTful API using API Gateway which can work with Lambda functions.

For this we add API Gateway as a trigger to both our lambda functions: getEmployeeProfile and addEmployeeProfile

apigateway1

After adding the trigger, Configure the trigger by adding API name, security options etc as show below.

apigateway3

Click on add and your API will be created.

apigateway4

As show above our API -(EmployeeProfile-API) is created.

Click on the API link, It will redirect you to the API gateway service where you can edit and configure(add GET/POST methods) your API.

As show below you can see your API console.

apigateway5

Click on Actions and delete the default “ANY” resource.

apigateway6

Then Create a GET method and add Lambda region and function the form as shown below.

apigateway7

Click on create method and below request-response blueprint will be shown:

apigateway8

Similarly we have add API trigger to our second Lambda function which addEmployeeProfile

apigateway9

Add and configure the API details and done before.

apigateway10

Configure the GET method to add model mapping template as show below

apigateway14

apigateway15

apigateway16apigateway17

now our API methods-GET and POST are setup.

We can proceed to deploying our API.

Select Deploy API from the dropdown.

Enter details like Stage name and description.

apigateway18

The invoke URL for prod stage will generated and you can send a GET and POST request to that URL.

apigateway19

We can do the Method Test to test out GET and POST method to confirm if our API is working fine.

apigateway20

If you get any access error you probably haven’t enabled CORS. Click on API dropdown in the dashboard and select Enable CORS.

apigateway21

Test the POST method also as shown below. pass the parameters in the Request Body.

apigateway23

Once tested the POST method you can again check you DynamoDb table to confirm if everything is working  fine.

apigateway24

Yes, So our API is ready.

Adding HTML Code to create Web page UI

create a file named profile.html and add following code:

Find the below code on my Github

html1

Add the following Script file: script.js

File the below code for script.js on my Github

html2

Now your Web files are ready.

Create an S3 bucket

let us create an S3 bucket to host our static web files.

Go to S3 under storage service.

s31

Create a bucket and details and set other permissions as default.

s32

As show in the above picture, Click on upload.

s33

Select the html and js files and click on upload.

After the files have been uploaded, click on the both files and click on “Make Public” to have them accessible over Internet.

s34s35

Click on the link to access your Html webpage over internet.

s36

Now let us add details to the form and save profile which inturns invokes Lambda API via AJAX call and API call Lambda event function(addEmployeeProfile) which calls DynamoDB and adds data to the database table.

s37

Ohk, if you get an above error, then it means you have not done CORS configuration for your bucket to access the API.

Add the below configuration in your bucket inside Permissions Tab.

s38

After adding the CORS configuration, refresh your webpage url and add the details again and click on Save profile.

It will send a response as “Profile saved“. Actually it call the API and saves the data in DynamDb table.

s39

To confirm, go to the DynamoDB table and refresh the table.

You will the new data added in your table, as show in below picture.

s40

Similarly, Click on “View all the Employee Profile” button to view the all the records present in DynamoDB table.

s41

FInd all the code files here.

So this was the end of this Post. Share your comments below.

Hope you all learned something. 🙂

16 thoughts on “How create a serverless website using AWS Lambda, AWS S3, AWS API Gateway and AWS DynamoDB with node.js? Full Tutorial!

  1. I have the following errors while i am trying to run.
    First i can not find the scripts2.js on the github
    Second on the scripts.js i have to change the following line to my api invoke URL?
    var API_ENDPOINT = “https://my-api-id.execute-api.region-id.amazonaws.com/stage-name/{resourcePath}”

    I would really appreciate if you could help me,Thanks.

    profile.html:49 GET https://s3.eu-west-2.amazonaws.com/changed/scripts2.js 403 (Forbidden)
    favicon.ico:1 GET https://s3.eu-west-2.amazonaws.com/favicon.ico 403 (Forbidden)
    jquery.min.js:16 OPTIONS https://(api Invoke URL) 403
    send @ jquery.min.js:16
    ajax @ jquery.min.js:16
    document.getElementById.onclick @ scripts.js:26
    profile.html:1 Access to XMLHttpRequest at ‘https:(api Invoke URL) from origin ‘https://s3.eu-west-2.amazonaws.com’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

    Like

    1. You’re getting 403 error because you have not enabled CORS in API Gateway. Please enable that. Also, sorry for confusion in script.js. there is only script.js file. It’s just script 2.js is same as script.js.

      Like

      1. so I removed the line with the script2.js
        i did enabled CORS in API Gateway but when i click on my api invoke URL i get {“message”:”Missing Authentication Token”}
        i did the tests for the api and worked

        favicon.ico:1 GET https://s3.eu-west-2.amazonaws.com/favicon.ico 403 (Forbidden)
        2jquery.min.js:16 OPTIONS https://api invoke URL 403
        send @ jquery.min.js:16
        ajax @ jquery.min.js:16
        document.getElementById.onclick @ scripts.js:26
        profile.html:1 Access to XMLHttpRequest at ‘https://api invoke URL’ from origin ‘https://s3.eu-west-2.amazonaws.com’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

        Like

  2. Keep up the good work but i got a issue,
    I enabled CORS in API Gate but i am getting the following error:
    Access to XMLHttpRequest at ‘https://jolxox2i86.execute-api.eu-west-2.amazonaws.com/prod’ from origin ‘https://s3.eu-west-2.amazonaws.com’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

    Like

    1. No ‘Access-Control-Allow-Origin’ header is present on the requested resource — THIS MEANS THAT THERE IS SOME MISTAKE WHERE YOU HAVE NOT ENABLED CORS PROPERLY. MY SUGGESTION WOULD BE TO DELETE THE API AND MAKE A FRESH ONE FROM BEGINNING.

      Like

  3. Hello,really nice work but you confused me a bit when created the api. First you trigger for getEmployeeProfile and then for addEmployeeProfile which you just added mapping template and nothing else?no post method or something?

    Like

  4. I have a confusion about the POST method in getEmpProfile-API and its configuration, which was not explained.
    Also what about the addEmpProfile-API,which was created and never appeared after and never used.
    I am beginner in AWS,it would be helpful if you reply.

    Like

  5. hi great work,thank you for providing for us , I was facing a small problem , i has inserted the dynamodb while i was retriving the data from the dynamodb i was unable to get the data in the sorted order,in the way how the data is getting on to the dynamodb

    Like

Leave a comment