Start tracking subscribers in AWS in under 30 minutes
Tags: aws, typescript, cloud, tutorial
Published: 2023-01-30 16:13:28

#### Building an audience is key to growing your brand.  You need a way to keep them informed!  This tutorial will have you tracking your subscribers in AWS in no time.

_Originally published at [jacoborshalick.me](https://jacoborshalick.me/posts/build-a-subscriber-rest-api-on-aws-in-under-30-minutes)._

---

We've all said it:

- I want to track my site subscribers
- I want to try out serverless computing on AWS
- I want to learn about IoC (Infrastructure as Code)

How can I do it all?

Here's your chance.  Finally, a tutorial where you learn while actually building something useful.

---

This tutorial will have you tracking your subscribers in AWS in no time.  By the end of this article, you'll have a REST API in AWS that stores subscriber records in a [DynamoDB](https://aws.amazon.com/dynamodb/) table.  You'll also automate the setup of all AWS infrastructure using [CloudFormation](https://aws.amazon.com/cloudformation/).

Need proof?  My [portfolio site](https://jacoborshalick.me) uses the APIs shown here to track subscribers.

If you want your own portfolio site, start with my [tutorial to setup your portfolio site in under 30 minutes](https://dev.to/jorshali/host-a-personal-blog-with-nextjs-and-aws-in-under-30-minutes-3431).  If you've already setup the portfolio site, I'll show you how to plug in your subcriber API at the end.

So let's get your subscriber API built!

## Before you Get Started

You'll need a few things. You may already have some of them:

- [Setup an AWS Account](https://aws.amazon.com)
- [Install Node.js](https://nodejs.org)
- [Install the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
- [Install the SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)

This tutorial assumes you are comfortable working in the terminal and using Git. Outside of that, the tutorial will walk you through what you need to know.

## About the AWS subscribers project

The complete source for the service you'll be setting up can be found on GitHub: [aws-subscribers](https://github.com/jorshali/aws-subscribers).  The project creates a REST API hosted on AWS that will support 2 simple requests:

> `POST /subscriber` *(creates a new subscriber)*

```
{
  email: "info@focus.dev"
}
```

> `PUT /subscriber/info@focus.dev` *(updates subscriber information allowing unsubscribe)*

```
{
  email:  "info@focus.dev",`
  unsubscribeAll:  true`
}
```

The components of the REST API that will be generated by the project can be represented in AWS by the following diagram:

![AWS representation of the REST API that will be generated by CloudFormation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/80g4nqil1tcju0emrdut.png)

This project serves as a great base for any functionality you may want to add.  Here's a quick summary of what the project provides you:

- Automated infrastructure and deployment using [AWS SAM](https://aws.amazon.com/serverless/sam/) and [CloudFormation](https://aws.amazon.com/cloudformation/)
- Standardized-project structure
- Lambda function coded in TypeScript
- NoSQL database access using [DynamoDB](https://aws.amazon.com/dynamodb/)
- REST API exposed through [API Gateway](https://aws.amazon.com/api-gateway/)

Let's get started!

## Setting up the Project

Once you have installed the necessary prerequisites you can setup the project with the following terminal commands:

```
$ mkdir <project-directory>
$ cd <project-directory>
$ sam init --location git@github.com:jorshali/aws-subscribers.git
$ npm install
```

The starter project will now be available in the project directory you specified.

## Create an AWS Profile

This is the most involved part of the tutorial, but it's a one-time process.

The steps below will guide you through the creation of a user with __Administrator__ rights and a local AWS profile for that user.  This will allow you to execute the remote commands that fully automate the setup of necessary infrastructure and code deployment.

We'll start by logging into the AWS Console.  You will want to search for and select the __IAM__ service.  Once in the IAM interface, select __Users__ in the left panel.  Here you will want to select __Add User__.

You will be presented with the __Create user__ steps.  Start by providing a valid user name and select __Next__.

![Define the username](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gfw5chvithfb32prsn8o.png)

On the next step, select the __Add user to group__ option and click the __Create Group__ button.  Search for __AdministratorAccess__ and select the check box to the left.  Name the group __Administrator__.  Scroll to the bottom and select __Create user group__.

![Apply AdministratorAccess to your group](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tft6scuqtf58a7u9f347.png)

You will now be taken back to the user permission options, but you will see your newly created __Administrator__ group.  Check the box to the left of your newly created group and select __Next__.

![Make your new user an Administrator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x1s6u2cix3rdrqh9c7wx.png)

This will take you to the __Review and Create__ screen.  Simply select __Create User__.

![Review and create the user](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rcvtbhkmmebl2egf5axk.png)

Now that we have our user, we need to generate an access key that will be used locally for running our commands.  Back on the __Users__ screen, select the user you just created.

![Select the user you just created](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgkos9g2numai5zo3n3j.png)

Select the __Security Credentials__ tab and scroll down to the __Access Keys__ section.  Here you will want to select the __Create access key__ button.

![Select the security credentials tab](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9sj1f4i9v9mojszdzm43.png)

When presented with Step 1, select the __Command Line Interface (CLI)__ option.  Select the "I Understand..." checkbox and select __Next__.

![Create an access key for the user](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qoin8aa3u7fherk1ojdu.png)

On Step 2, there's no need to create any description tags so simply select __Create Access Key__.  You will now see the following with your __Access Key__ and __Secret Access Key__.  Leave this page open for the next step.

![Specify Command Line Interface (CLI) access](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lhjzq3mgx5x8nrhyhmiw.png)

Now in your terminal, execute the following command:

```
aws configure --profile aws-subscribers-prod
```

This will ask you for your __AWS Access Key ID__ and __AWS Secret Access Key__.

Open back up  the page you left open so you can copy and paste those values.  Complete the questions as follows:

```
AWS Access Key ID [None]: <copy and paste the Access Key ID here>
AWS Secret Access Key [None]: <copy and paste the Secret Access Key here>
Default region name [None]: us-west-2
Default output format [None]: json
```

That's it!  The hard part is over.  Now let's get this service deployed.

## Building the Project

We have to start by telling the AWS CLI that we want to use the profile we just created to deploy the project. For example, in your terminal on a Mac:

```
$ export AWS_PROFILE=aws-subscribers-prod
```

Now make sure you are in your project directory in your terminal.  Once there, we can build the project with AWS SAM:

```
$ sam build --beta-features
```

__Note__:  The beta-features flag is necessary since we are using TypeScript.

Once the build completes, it's time to deploy.

## Deploying the Project to AWS

You can now deploy to your account using the profile you selected:

```
sam deploy --guided
```

While being guided through the deployment, the defaults are generally recommended.  There are only a couple of exceptions. You can customize the Stack Name to something specific to your project.  When presented with the following prompt, answer __y__:

```
SubscriberFunction may not have authorization defined, Is this okay? [y/N]: y
```

Once the deployment completes, it will print out 3 results:

![Results from the SAM deployment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6r1wd5ispk0z1t5uh0ey.png)

Hang onto the __WebEndpoint__ value as this is the URL you will be using to call your Subscriber API.

You can now login and browse your AWS Console to see the various components that were installed. For example, you will find the `subscriberFunction` within the Lambda console.

![Lambda console with subscriberFunction](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x0p53e18r5pv2fts3tj4.png)

## Configuring your personal site (optional)

If you followed my [tutorial to setup a portfolio site](https://jacoborshalick.me/posts/nextjs-and-aws-amplify-host-a-personal-blog-in-under-30-minutes) you can start using your API immediately.  In your `personal-site-starter` project, open the file `src/constants.ts`.

In this file, find the constant `SUBSCRIBER_REQUEST_URL` and replace the value with the __WebEndpoint__ value that was output by the SAM deployment.

Save the file and open a terminal in your `personal-site-starter` directory.  Start your local server by running the following command:

```
npm run dev
```

Open your site in your browser at [https://localhost:3000](https://localhost:3000).  As soon as the landing page opens, put in your email address and click __Subscribe Now__.

Now open your AWS console and search for __DynamoDB__.  Open it and in the left navigation select __Tables > Explore Items__.  Under __Tables__ select __SUBSCRIBER__.

![Entries in SUBSCRIBER table in DynamoDB](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ww5920p4t05f9nv54dm2.png)

Here you will see an entry for your email address!

If everything worked, simply commit these changes and push them to your Git provider.  AWS Amplify will automatically redeploy your site with the subscriber API configured.

## Running the Service Locally (optional)

You can test your service locally using Docker. You can [install Docker here](https://docs.docker.com/get-docker/). Once Docker is installed, you can start the project locally with the following commands:

```
$ sam build
$ sam local start-api --port 8080
```

Once this is running you can test the API at: `http://127.0.0.1:8080/subscriber`

If you are testing the `personal-site-starter` locally, simply change the value of `SUBSCRIBER_REQUEST_URL` in `src/constants.ts` to: `http://127.0.0.1:8080`

## Project Organization

This guide is purely focused on getting the Subscriber API up-and-running on AWS quickly. In an upcoming series, I will walk you through more project specifics.

If you want to get started customizing the project right away, here's a quick rundown of the project structure. You can browse this code from the project root in an IDE like [VS Code](https://code.visualstudio.com):

- `template.yml`: the CloudFormation template that defines the service requirements. If you want to customize the REST API URL, DynamoDB table definitions, etc, this is the place to do it.
- `subscriber`: contains the code for the `subscriberFunction`. This is where you will find the `package.json` dependency definitions, TypeScript files, and general configuration.
- `subscriber/index.ts`: the TypeScript function that handles all `/subscriber` requests. You can use this to experiment with your own functionality.

## Your service is live on AWS

That's it!  You now have an API for capturing subscribers and allowing them to unsubscribe.

If you run into any issues along the way, feel free to ask questions or post issues at:  [aws-subscribers](https://github.com/jorshali/aws-subscribers).

## What's next?

In the next post I'll be showing you how to register a domain and connect it through [Route 53](https://aws.amazon.com/route53/) in AWS so you can share your site with the world.