Building Serverless URL Shortener Service on AWS
Tags: aws, serverless, urlshortener, dynamodb
Published: 2021-08-23 16:21:58

<h4> Walk-through of a serverless implementation of an URL Shortener Service without AWS Lambda Functions</h4>

---

## The AWS Serverless Ecosystem
> Serverless is a way to describe the services, practices, and strategies that enable you to build more agile applications so you can innovate and respond to change faster. With serverless computing, infrastructure management tasks like capacity provisioning and patching are handled by AWS, so you can focus on only writing code that serves your customers.

***Serverless Computing = FaaS [Functions as a Service] + BaaS [Backend as a Service]***

### Serverless Services of AWS:

* **Compute**: AWS Lambda, AWS Fargate

* **Storage**: Amazon DynamoDB, Amazon S3, etc.

* **Application Integration**: Amazon API Gateway, etc.

---

## Introduction

In this walkthrough, we are going to develop an URL Shortener Service using various services of the AWS Serverless Ecosystem. We are going to focus mainly on the backend of the application.

To implement our project in a simplified way, we will use only the 2 most important services: the **API Gateway** and **DynamoDB**.

![Architecture Diagram](https://cdn-images-1.medium.com/max/2000/0*mdA4N2pJd9rpJ2ve.jpeg)*Architecture Diagram*

### AWS Lambda

AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers, creating workload-aware cluster scaling logic, maintaining event integrations, or managing runtimes. With Lambda, you can run code for virtually any type of application or backend service ΓÇö all with zero administration.

In this application, we are not going to use AWS Lambda, since our application runs on simpler logic ΓÇö i.e. to store short-URLs into the Database and re-direct to the long-URLs once we call the short-URL.

### Amazon 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. APIs act as the ΓÇ£front doorΓÇ¥ for applications to access data, business logic, or functionality from your backend services.

In our application, we are going to utilize the functionality of the API Gateway through which we can perform ETL operations during the transit of data between the API Gateway and DynamoDB.

### Amazon DynamoDB

Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. ItΓÇÖs a fully managed, multi-region, multi-active, durable database with built-in security, backup and restores, and in-memory caching for internet-scale applications.

DynamoDB can handle more than 10 trillion requests per day and can support peaks of more than 20 million requests per second.

---

## Getting Started

To follow this project, you only need to have an AWS account. The entire application would be developed within the AWS Web Console.

Let's understand the workflow of the application. We are currently focussing on 2 main features prevalent to all URL-Shorteners.

### 1. Storing the Short-URL, Long-URL and owner inside DynamoDB

In the backend, once a user sends a POST request to the Route, with all the required parameters, the API Gateway receives the data, transforms it and pushes it into the DynamoDB.

### 2. Redirecting to the Long-URL once the short-URL is hit

Once a user mentions the short-URL in the HTTP header, the API gateway receives the data, processes it and searches it inside DynamoDB. Once the corresponding Long URL is found, the API Gateway redirects to the Long URL.

---

## Setting Up DynamoDB Database

First of all, we need to configure our Database. For that, we need to create a Table.

The table would be consisting of 3 Columns: longURL , **shortId** , owner . We would be using the shortId attribute as the **Primary key** of the table.

In the configuration, please use the exact names mentioned.

* **Table Name:** URL-Shortener

* **Primary Key:** shortId

* **Table settings:** Use Default Settings

Once you create the Table, you would land on the following page mentioning all the Table Details:

![](https://cdn-images-1.medium.com/max/2770/1*MM4b0kHgyxTl9c41IdMu3g.png)

--- 

## Setting up the API Gateway

This is the most important service in our architecture. Through this service, we are going to perform multiple operations.

1. Create API Endpoints for **GET** and **POST** requests.

1. Transform request parameters received from the API into DynamoDB understandable format.

1. Convert the response received from the DynamoDB into a format understandable by browsers for re-direction.

We need to create an API of the type Rest API from the API Gateway console.

After selecting the **REST-API Gateway type**, we need to select the following configurations.

* **Protocol**: REST

* **Create a new API:** New API

* **API name:** URLShortener

***This would create a new API.***

![API Gateway Console](https://cdn-images-1.medium.com/max/3786/1*XJ-fOjexTTBqqSc1LRqUtg.png)*API Gateway Console*

Now, we need to create an New Resource under the / route. The name of the resource is set as: url-shortener .

Under this resource, we need to create multiple methods for **GET **and **POST **requests.

--- 

## Setting Up POST Request

Under the /url-shortener resource, we need to create a method named ΓÇ£POSTΓÇ¥. In this method, we are going to modify our POST request.

Once the POST Method is selected, we have to use the following information during its setup:

* **Integration type:** AWS Service

* **AWS Region:** ap-south-1 [region where the DynamoDB Instance would be running]

* **AWS Service:** DynamoDB

* **HTTP method:** POST

* **Action:** UpdateItem

* **Execution role:** [ IAM Role in which DynamoDB write permissions are given ]

Once the setup is completed, we land on the following page:

![](https://cdn-images-1.medium.com/max/3736/1*tWSNBqlziVYtfCk8nl7--g.png)

Now, we need to transform the request parameters received from the client into something that would be understood by DynamoDB.

For this, we are going to utilize the Integration Request feature of the API Gateway. Through this feature, we are going to add a **Mapping Template** based on which the transformation would take place.

On clicking the **Integration Request** from the above page, we would be landing on the following page:

![](https://cdn-images-1.medium.com/max/2496/1*VHxrOJ79sdB0fV1BnjwQXA.png)

Under the **Mapping Templates section**, we need to add the following code:

{% gist https://gist.github.com/Lucifergene/180738ec994ce28d4b4d8fa7c71bbab7 %}

Now, we have set up the process through which data would be saved into the DynamoDB. But now, we have to also format the Response that DynamoDB would be sending, to a format understandable by the Client.

For this, we need to set up another **Mapping Template** in the Integration Response section.

![](https://cdn-images-1.medium.com/max/2640/1*hLODslObT3R46hzLhyMIdw.png)

Under the **Mapping Templates section**, we need to add the following code:

{% gist https://gist.github.com/Lucifergene/39bf8dc169f4ca6d1f1d5eaa591f5e9e %}

Once this is set up, the response of the DynamoDB would be converted in a form understandable by the client.

Thus, we have set up our POST request, which would save the request parameters in the DynamoDB and would send the response back to the client. To test, we need to click on the **TEST **option from the above console.

In the Request Body, we need to type the following:

    {
      "longURL": "[https://www.google.co.in](https://www.google.co.in)",
      "owner": "Avik",
      "shortURL": "Google"
    }

On submitting the above JSON, we must receive a 200 Status code and a similar response body as the following. Thus we have successfully saved the contents to the DynamoDB.

![](https://cdn-images-1.medium.com/max/3840/1*Zbiyxi-mWQnaBgUynOupLg.png)

--- 

## Setting Up GET Request

The GET request is somewhat different from the POST request. Here, the user would be appending the short URL to the API endpoint. This shortURL would be sent to the DynamoDB by the API Gateway to perform the search operation. Once the associated long URL is found, the API Gateway automatically re-directs to the long URL.

Under the /url-shortener resource, **we create another resource named as {shortURL}**, which would be having a dynamic resource path, as it is the place where the short URLs would be appended.

Inside the newly created sub-resource, we create the GET request with the following settings:

* **Integration type:** AWS Service

* **AWS Region:** ap-south-1 [region where the DynamoDB Instance would be running]

* **AWS Service:** DynamoDB

* **HTTP method:** POST

* **Action:** GetItem

* **Execution role:** [ IAM Role in which DynamoDB write permissions are given ]

Once the setup is completed, we land on the following page:

![](https://cdn-images-1.medium.com/max/3732/1*5i0yhSFXoGSWayNh-u_41w.png)

Now, we have to perform 3 transformations while the data would be transferred back and forth between the API Gateway and DynamoDB.

### A. Integration Request

First, we need to transform the request parameters received from the client into something that would be understood by DynamoDB. For this, we are going to utilize the **Integration Request **feature of the API Gateway. Through this feature, we are going to add a **Mapping Template** based on which the transformation would take place.

On clicking the **Integration Request** from the above page, we would be landing on the following page:

![](https://cdn-images-1.medium.com/max/2588/1*SsCvdX0_OI2qed0clnCcrQ.png)

Under the **Mapping Templates section**, we need to add the following code:

{% gist https://gist.github.com/Lucifergene/ca5e96a9744d4eeecd478ba6d097600b %}


### B. Method Response

We know that for URL redirections, **302 HTTP Status code** is used. Therefore in the response header, we need to set the appropriate status code since by default **200**is** **set.

In the **Method Response** section, we need to **delete the 200 status code association** and **add the 302 HTTP Status Code**. To instruct the API gateway to redirect to the URL set in the Location key in the Response header, we need to add it to the corresponding 302 Response Header.

![](https://cdn-images-1.medium.com/max/3840/1*RNh5t9eZZuCADRHEOveNdg.png)

### C. Integration Response

After setting up the **Method Response**, now, we have to also format the Response that DynamoDB would be sending, to a format understandable by the Client.

For this, we need to set up another **Mapping Template** in the Integration Response section.

![](https://cdn-images-1.medium.com/max/3796/1*NgGf_dF9O64z6UtiTxYbAA.png)

Under the **Mapping Templates section**, we need to add the following code:

{% gist https://gist.github.com/Lucifergene/b2be264e74bf4cb5c38bf57bd5f710af %}

Thus, we have set up our GET request, which would redirect the short URL to the actual LongURL after fetching it from DynamoDB.

To test, we need to click on the **TEST** option from the above console. In the {shortId} field, we need to enter the shortId of the URL and click on the **TEST** button.

![](https://cdn-images-1.medium.com/max/3744/1*RvGf85HGlF3uw7mNlL9JAQ.png)

Thus we have received a **302** response code and upon studying the response header, we see a location key that contains the actual Long URL.

---

**And we reached the end of the solution!!!**

You can visit the repository from below:

{% github Lucifergene/Serverless-URL-Shortener %}

---

You can reach out on my [Twitter](https://twitter.com/avik6028), [Instagram](https://instagram.com/avik6028), or [LinkedIn](https://linkedin.com/in/avik-kundu-0b837715b) if you need more help. I would be more than happy.

If you have come up to this, do drop an :heart: if you liked this article.

**Good Luck** :sunglasses: and **happy coding** :computer: