Cloud Resume Challenge — Back End

Melissa Richard
8 min readNov 23, 2023

--

Greetings Cloudlings!

Before we get to the good stuff I must begin this article with a correction to my system diagram as well as an explanation.

A major step in completing the challenge is setting up an accurate visitor counter on our resume page. To do this we will need to use JavaScript to write code that adds the visitor counter to our webpage HTML. That Javascript code makes a call to a database, DynamoDB in our case, which is holding the number of visitors to the resume webpage. The database returns the call with the number of visitors and that number is shown on the webpage as directed by the JavaScript code.

As part of setting up this back end of our web page we need an API to communicate with our database and a Lambda function to trigger the communication with our database. You do not want your JavaScript code “speaking” directly with your database. That’s what the API and Lambda function handle, they act as the middle man to protect your database from being fiddled with all willy nilly. The challenge suggests using AWS API Gateway and AWS Lambda for this purpose which is what was reflected in my original diagram below.

Created by Melissa Richard using draw.io

However, in working through this project I have learned about Lambda function URLs. A Lambda function URL creates an address or endpoint API where you can directly call the Lambda function which then “speaks to” and updates the database.

In this challenge we are only using one Lambda function which does one simple job. In a more complex system where we need multiple Lambda functions I would use API Gateway as suggested, but here we have a rather simple system with a singular Lambda function and a straightforward job for that Lambda function to complete. So, I made the decision to alter the system and use a Lambda function URL instead of API Gateway. My updated system diagram is below.

Created by Melissa Richard using draw.io

As you can see, the only thing that has changed is the removal of API Gateway. We will be triggering the Lambda function directly by using its URL. The Lambda function then calls on the database to get the updated visitor count number and our system still works as needed.

Now, let’s begin.

Step 1: DynamoDB

Again, using the console to set up a DynamoDB table is pretty simple. Navigate to the DynamoDB main page and press the Create Table button.

Choose a name for your table. Unlike S3 buckets, a DynamoDB table does not need to be globally unique so choose whatever works for you. It can be as simple as cloudresumechallenge2023.

You also need to add a Partition Key name. This name can be as simple as “id” or more specific like “cloudresumeviewskey”. But you do need to keep the partition key name exactly the same when we use it in our Lambda function.

Next, add an item to the table. This will represent our actual views counter and can have a simple name like views with a number value of 0 since we don’t have any views yet.

And badaboom badabing. We’re done setting up our database.

**For our partition key use string value of 1.

Step 2: Lambda function

Here is where it gets fun. And by fun I mean very stressful because why would Forrest make me write Python? Sometimes I can’t even write my own name properly! But I digress …

Head over to the AWS Lambda homepage and click the Create function button.

We’re going to author this function from scratch and name it whatever we want but something simple like “cloudresumefunction” will do. I chose to use Python as our runtime language because that’s the only available language that I’ve dealt with before and when I googled that what everyone else who completed this challenge told me to do. Now is not the time to be a trendsetter.

For our default execution role we are going to let Lambda create a new role for us because it’s a managed service and it’s helpful like that. (If you’re unfamiliar, a role allows our Lambda function to access other services so that we don’t have to manually facilitate communication between the services.)

Under Advanced Settings, enable function URL. This feature keeps us from needing the AWS API Gateway service. The function URL provides an HTTP(S) endpoint that we will use in our Javascript code to call the function and trigger the process of pulling the views count from the database, adding to the views count, and updating the views count so it’s accurate when we pull the count the next time. Got it? No? Don’t worry, it comes together eventually.

Although we are not enabling Cross-origin resource sharing (CORS) right now, keep it in the back of your mind. We will come back to it. Enabling CORS and specifying our resume webpage domain as the only endpoint allowed to access our Lambda function will prevent anyone but our own helps keep our Lambda function secure. But for now leave it disabled for testing purposes.

Once your function is created you should be able to find its function URL and see the function code. If you click the function URL link you should be taken to a new webpage that says “Hello from Lambda” which is the default code for a new Lambda function.

Now here is where things got sticky for me. In the code section we need to replace the small bit of code that rendered the “Hello from Lambda” message with our own Python code that interacts with the DynamoDB table and prints the current view count. I had headache induced trouble getting this code to work. There are quite a few examples online that I’m sure you can find very easily but they were not working for me.

But have no fear, after a few hours of cursing, Googling, and harassing ChatGPT I was able to come up with a code that worked and I’m providing it to you for free as my bit of charity this holiday season. I should get a humanitarian award for this.

import json
import boto3

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('YOUR DYNAMODB TABLE NAME')

def lambda_handler(event, context):
response = table.get_item(Key={'ID':'1'})
views = response['Item']['views']
views = views + 1
print(views)

response = table.update_item(
Key={'ID':'1'},
UpdateExpression='SET #v = :val',
ExpressionAttributeNames={'#v': 'views'},
ExpressionAttributeValues={':val': views}
)

return views

If you are not familiar with coding or Python specifically I’ll break it down so you can insert the appropriate names for your code.

We start off by importing the necessary libraries — json and boto3. “boto3” is the Python library/SDK for AWS that allows Python code to send API requests to other AWS services.

“Lambda_handler” is the name of our function and it creates a variable named response that pulls an item from the named DynamoDB table with the Key-value pair specified. Make sure that however you have defined your partition key and it’s value is represented here. And this information is case specific. If it says “id” in your DynamoDB table then it needs to say “id” in this code. Not “ID” or “Id”, be careful here or you will cause yourself a headache.

Next, the code sets up a new variable named “views” which is pulling the views information for Item with ID 1 from our DynamoDB table. The code then adds 1 because we want this to update with each view of our page and print that number.

Now we need to update the number of views in the DynamoDB table so that when we pull the views count again we’re getting correct information. This next part of the code is where things got tricky for me and I had to use Google-fu and ChatGPT to help me out. I was getting a conflict error with the variable named “views”. To get around this I used ExpressionAttributeNames to set an alias for “views” and then ExpressionAttributeValues to map the alias to the actual value that needs to be updated.

I truly hope that I explained that in a coherent way.

Once you’re done with your code press the “deploy” button to save and update your function. Move over to the Configuration setting to the right of Code and you should see a tab for “Function URL”. This is where you want to go in and enable CORS. For now “*” will be our allow origin and if you click on your function URL a new page should open with a number on it. This represents your page views and the number should grow by 1 every time your refresh the page. You can also test this in your terminal using the curl command with your function URL. The Postman application is another great way to test your API endpoints.

Okay, now we move on to the Javascript so that we’re actually showing the views counter on our webpage.

Step 3: JavaScript

This part should be fairly easy compared to working out the appropriate Python code.

If you’re new to Front-End Development you probably wrote the front -end of your website using only HTML and CSS or found a website template that only used HTML and CSS. In either case you won’t already have a .js file in your project files. Don’t fret. Just go into your code editor (I used VS Code) and create a new file called “index.js”.

Next you want to add the following code to your Javascript file:

const counter = document.querySelector(".counter-number");
async function updateCounter() {
let response = await fetch("YOUR LAMBDA FUNCTION URL HERE");
let data = await response.json();
counter.innerHTML = `${data}`;

updateCounter();

This code fetches the data from your Lambda function and creates a template literal so that the Javascript can be inserted into the HTML.

Now you need to go back into your HTML file and tell it where you want to display your views counter. I can’t help you with this since I don’t know what your webpage looks like but the HTML should look something like this no matter you put it:

<a>Views:</a> <a class="counter-number"></a>

And that about wraps up the Back-End!

My resume website is here: https://resume.richmello.cloud/

If you click on my name you will be taken to my LinkedIn page. Feel free to add me.

Congratulate yourself again. I definitely had a celebration 10-piece nugget from McDonalds but you know, you do you.

** Don’t forget to update your CORS allow origin with your website domain

I’ll see back here in a few days for the final part of this challenge — Infrastructure as Code and the CI/CD pipeline creation.

--

--

Melissa Richard

Hello! Thank you for checking out my page. I'm an Attorney exploring the exciting world of web3 - Cloud, AI, and Blockchain.