Building a Serverless Back-end with AWS

Connie
9 min readJul 24, 2020

--

Contrary to its name, serverless architecture does have servers. However, developers do not need to know anything about them — managing and provisioning servers are the responsibilities of the serverless platform host (in this case, AWS). Developers only need to handle writing code and building their application. Another benefit of serverless is that developers will only be charged for the resources they use.

In this article, we will be using the following three services from AWS to implement a serverless back-end: Amazon API Gateway, AWS Lambda, and Amazon DynamoDB.

When a client makes a HTTP request to a public API endpoint provided by API Gateway, a Lambda function will be invoked. The Lambda function manipulates the database provided by DynamoDB and then sends the response back to the client.

Serverless Architecture
Serverless Architecture

Want to read this story later? Save it in Journal.

Prerequisites

  • AWS account with IAM (Identity and Access Management) user set up
  • Node.js

We’ll be building a back-end that will handle requests from the client to get information from a database of ramen restaurants in New York City.

We will write a Lambda function that will be invoked every time a user requests a restaurant. The function will get the restaurant from the DynamoDB table and respond to the front-end of the application with the details of the specified restaurant. The Lambda function will be invoked from the browser via API Gateway.

Creating a DynamoDB Table

Before we can implement the Lambda function, we will need to create a table in DynamoDB. In your AWS console, navigate to DynamoDB and click the Create table button to begin.

1. Let’s name the table “RamenRestaurants”.

2. Give the table a primary key (or partition key) of “RestaurantId” with a type of “String”. The primary key is a unique identifier for each item in the table. It is used for querying and accessing the data in the table. We will be querying the table via the RestaurantId later on when we write the lambda function.

3. Use default settings should already be checked off by default.

4. Hit Create.

5. Congrats! You’ve just created your first DynamoDB table. The next screen will show you an overview of your new table.

6. To add items to your new table, click on the Items tab and then hit the Create item button. Provide ‘1’ as the RestaurantId. To add attributes to the item, hit the ‘+’ button and choose Append and choose a type accordingly. I am adding the following attributes and information as my first item but feel free to create yours however you’d like.

7. Let’s add a few more restaurants into our database.

Creating a Lambda Function

Now that we have our DynamoDB table, we can create a Lambda function to handle an HTTP request. Navigate to the AWS Lambda console.

1. Click the Create function button,

2. The Author from scratch option is the default choice. We will keep that option selected.

3. We’ll name the function ‘ramen_read’ and select Node.js for the Runtime language. (AWS Lambda supports other runtimes but for this article, we will be be using Node.)

4. Next, click on the Create function button and on the next screen, you’ll see the details of your new lambda function.

5. If you scroll down a bit, you’ll see the Function code section, with some sample code. You can write functions right in the console editor, which works well for simple functions. Before we get into actually writing it, let’s go over some syntax of a typical lambda function.

Every lambda function has a handler, which is a method that processes events.

As shown above, the handler method takes in three arguments: event, context, callback. The event object contains information from the invoker, which passes on information in the form of a JSON-formatted string. The context object contains information about the function itself, the invocation request, and its runtime environment. The callback argument is a function that takes in two arguments: an error, and a response. The callback function returns either the error or the response to the invoker.

6. Now, let’s start writing our “ramen_read” function! As mentioned before, you can write functions directly in the AWS Lambda console code editor. However, we will be writing our function in locally. Feel free to use your favorite IDE. This allows us to be able to create a git repository for our work.

In your project folder, let’s create a new directory called “ramen_read.” Within that directory, run npm init and create a package.json file.

Create a new file called index.js and paste the below code within that file. Don’t forget to npm install aws-sdk!

To access the DynamoDB table, we are using the AWS Document Client. Theparamsobject is a JSON object containing the parameters needed to query the table. Then, we call the query method on the document client.

Next, compress all the contents of the “ramen_read” folder into a zip file. On the Function code section of the AWS Lambda console, there is an Actions button on the top-right corner. Click on it and select Upload a .zip file to upload the zip file to AWS.

Note: Another way to upload your zip file is by using AWS CLI. This would involve installing AWS-CLI, configuring user permissions, and running a few commands to upload the zip file from your terminal.

7. Before we can test the lambda in the console, we need to configure permissions. Otherwise, if you try to invoke the function, you will receive an Invoke Error: ”errorType”: “AccessDeniedException”.

On the lambda function console, click on Permissions, and then click on the Role name.

A new tab will open to the IAM console and show you a summary of the role and permissions policies attached to the “ramen_read” lambda. Click on the blue Attach policies button. On the next page, search “DynamoDB” and select the AmazonDynamoDBReadOnlyAccess policy. For our example, we only need read only access. However, for other functions you may write in the future, you may need full access. Choose the one that best matches your needs. Click on the Attach policy button.

8. Now we can test our lambda in the console! Go back to the AWS Lambda console for the “ramen_read” function. Click on the Test button at the top of the page.

A window will pop up to configure test events. We will provide a RestaurantId of 1 in JSON format. Name your event and click Create.

Click on the Test button again and you should see a successful execution result on the console, along with the response returned by the function execution. In this case, it is the information we provided in our database for Nakamura, which has a restaurant id of 1.

Creating a REST API with API Gateway

Now that we have a lambda function, we will use API Gateway to get a public API endpoint that that will trigger the function. Navigate to the API Gateway console.

1. Click on Create API.

2. Choose REST API on the next screen and click Build.

3. We will name the API “RamenRestaurantsAPI” as well and Create API.

4. On the next screen, click on Action and select Create Resource. The Resource Name and Resource Path will be “restaurant.”

5. Back on the RamenRestaurantsAPI screen, click the /restaurant resource you just made and then click Actions again and Create Resource. This time, the Resource Name will “id” and the Resource Path is “{id}”. This is how we will pass in the id of the restaurant in our query; for example, a GET request to /restaurant/id.

6. Now we will Create Method. Select GET as your method and hit the checkmark.

7. The Setup for the method will pop up on the right.

The Integration type is Lambda Function.

Choose your Lambda Region. You can find it in the navigation bar in the top-right corner next to Support. In my case, my region is “us-east-1” and in the navigation bar, it says N. Virginia. The region is just a geographic location where Amazon has data centers. Usually, your region is the one you are physically located closest to.

Lastly, fill in the name of the Lambda Function and click Save.

8. Click OK when the next window pops up confirming permissions.

9. Now you will see the /restaurant — GET — Method Execution. We will need to create a mapping template for the Integration Request.

Mapping templates are how API Gateway transforms a request before it is sent to the back-end. After you click on Integration Request, you will see the last option on the screen for Mapping Templates.

Select “When there are no templates defined” for Request body passthrough. Click Add mapping template and input “application/json” in Content-Type.

Underneath that box, a text editor will appear. The JSON for the mapping template is: {“RestaurantId”: “$input.params(‘id’)”}

Don’t forget to hit Save!

10. Go back to the Actions button at the top of the page and select Deploy API. On the window that pops up, create and name a deployment stage. We will just call it “prod” and then hit Deploy.

11. After you hit deploy, you will be directed to the Stages page. Under the stages on the left-hand side, select the GET method that we created.

The invoke URL for the method is at the top of the screen.

12. Input the invoke URL into your browser address bar and replace {id} with “1.” You will see the below response!

Great! Your back-end is all set!

Follow these steps to create other lambda functions, or new methods within your API as needed for your application. Make sure to re-deploy the API whenever you make changes.

📝 Save this story in Journal.

👩‍💻 Wake up every Sunday morning to the week’s most noteworthy stories in Tech waiting in your inbox. Read the Noteworthy in Tech newsletter.

--

--