Hardware FixRecommendedDevice not working? Your driver may be the problemCheck updates for common hardware issues.Fix DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk8 min

Cloud Resume Challenge Week 2: Building the Serverless Visitor Counter with Lambda, DynamoDB and API Gateway

Week 2 of the Cloud Resume Challenge adds a visitor counter backed by API Gateway, Lambda and DynamoDB. Here is the request flow, the design choices the challenge leaves open, and the steps and failure modes that matter.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Week 2 of the Cloud Resume Challenge adds a visitor counter to your resume site. The page calls an API, API Gateway passes the request to a Lambda function, and that function reads and updates a counter stored in DynamoDB. The browser never talks to DynamoDB directly. This guide walks through that backend, separates what the challenge requires from the design choices you have to make yourself, and flags the points where people most often get stuck.

What the challenge requires and what it leaves to you

The official Cloud Resume Challenge page, published by AWS, asks for three things in this step: the resume webpage must display a visitor count, a backend must retrieve and update that value, and the backend resources should be managed as infrastructure as code. It recommends DynamoDB for storage and API Gateway with Lambda for the backend. It also says not to connect browser JavaScript directly to DynamoDB, and it does not require the console to be used for building resources.

As an Amazon Associate I earn from qualifying purchases.

The challenge does not specify the following, so each one is a decision you make and should be able to explain:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Whether you use an HTTP API or a REST API in API Gateway
  • The route path, HTTP method, and JSON response shape
  • The DynamoDB table name, key schema, and item layout
  • What a “visit” means for the counter
  • The exact CORS policy
  • Whether you use AWS SAM or Terraform

The choices below are the ones used in this walkthrough. They are a reasonable starting point, not the only correct answer.

#1 Best Overall
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
  • Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
  • Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
  • CanaKit Turbine Black Case for the Raspberry Pi 5
  • CanaKit Low Noise Bearing System Fan
  • Mega Heat Sink - Black Anodized

How the pieces fit together

The request path is:

Resume page JavaScript → API Gateway → Lambda → DynamoDB

Each service has one job:

  • The page script sends an HTTP request when the page loads and writes the returned number into the HTML.
  • API Gateway exposes a public HTTPS endpoint, matches the request to a route, and invokes the integration behind it. It also handles CORS headers if you configure them.
  • Lambda runs your code. For this project, the code increments the counter and returns the new value.
  • DynamoDB stores the counter as an item, so the value survives between invocations and is not held in memory by the function.

The response travels the same path in reverse. If any hop fails, the page should still render, which is covered in the failure section below.

Step 1: Design the data model and define the counter

Start by deciding what the number means, because the code and the table design follow from that decision.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
CanaKit Raspberry Pi 5 16GB Starter Kit PRO - Turbine Black (128GB Edition) (16GB RAM)
  • Includes Raspberry Pi 5 16GB with 2.4Ghz 64-bit quad-core CPU (16GB RAM)
  • Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
  • CanaKit Turbine Black Case for the Raspberry Pi 5
  • CanaKit Low Noise Bearing System Fan
  • Mega Heat Sink - Black Anodized
What you count How it is implemented What the number honestly means
Requests to the endpoint Increment once per API call, with no identity check Page loads and reloads, including bots and your own testing
Unique visitors Requires an identifier per visitor (for example a cookie or hashed client detail) and a record of seen identifiers Closer to distinct browsers, but still not exact people; adds privacy and storage considerations

For the first Week 2 build, a request counter is the simpler choice. Label it as a page-view or request counter on the page, not as “unique visitors,” unless you have implemented deduplication.

Use a single item with a simple partition key. For example, a table called visitor-counter with a string partition key named id, and one item whose id is visits and which holds a numeric attribute named count. A single-item design is fine for a resume site and keeps the access pattern trivial.

Keep the table in the same AWS region as the Lambda function. The region is part of the endpoint and of the resource names, and mismatches are a common source of confusion later.

Rank #3
RasTech Raspberry Pi 5 8GB Kit 64GB Edition with Active Cooler,27W GaN 5.1V5A USB-C Power Supply,Pi5 8GB Board,64GB Card Readers Kit,Pi 5 Case,Dual 4K Micro HD Out Cables and User Manual
  • Pi5 8GB Pack: RasTech Pi 5 8GB kit includes 1 x Pi5 8GB board ,1 x 64GB Card, 2 x Card Readers,1 x Active Cooler,1 x Case for Pi5, 2 x 4K Micro HD Out Cable,1 x GaN 27W 5A USB-C Power supply,1 x Screwdriver and 1 x instructions.
  • Pi5 8GB Board: The Pi5 board is equipped with a 64-bit quad-core Arm Cortex-A76 processor running at 2.4GHz and an 800MHz VideoCore VII GPU with support for OpenGL ES 3.1 and Vulkan 1.2, which delivers a significant increase in graphics performance. Dual HD Out 4Kp60 display outputs and a built-in dual 4-channel MIPI camera/display transceiver provide state-of-the-art camera support. The Pi 5 offers a 2-3 times increase in CPU performance compare to Pi4.
  • Important Graphics Features: Equipped with an 800MHz VideoCore VII GPU and providing better graphics performance, suitable for multimedia applications,gaming,and graphics intensive tasks.Provides 1 UART interface,1 card slot that supports high-speed operation, 2 USB. 3 0.5 ports that support synchronous 0Gbps operation,2 USB 2.0 port ports,2 4Kp60 display outputs that support HDR.Built-in dedicated dual 4-channel 1Gbps MIPI DSI/CSI connectors,triple the total bandwidth.
  • Cooling Kit for Pi 5: Compatible with Active Cooler for Raspberry Pi5, It can provide Pi 5 board with better cooling effect in using. The Case can accurately access usb-c power jack,Micro HD Out ports, usb ports, Ethernet jack, card slot, power button, 4-lane MIPI DSI/CSI connectors and so on, and it also supports installation of cooling fan.
  • 64GB Card Kit and GaN 27W USB-C Power Supply: With extra 64GB card to store more files and card readers for multiple medium, keep better performance for Raspberry Pi 5, 27W USB C Power Supply is Compatible with Pi5 8GB, offers a variety of output voltage options, including 5.1V at 5A, 9.0V at 3.0A, 12.0V at 2.25A, and 15.0V at 1.8A, providing for different device requirements.

Step 2: Write the Lambda function

The challenge recommends Python with boto3, which is the AWS SDK for Python. The handler below is one illustrative pattern, not a required solution. It reads the table name from an environment variable, increments the counter atomically, and returns JSON.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import json
import os
import boto3

table = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME'])

def handler(event, context):
    result = table.update_item(
        Key={'id': 'visits'},
        UpdateExpression='ADD #c :inc',
        ExpressionAttributeNames={'#c': 'count'},
        ExpressionAttributeValues={':inc': 1},
        ReturnValues='UPDATED_NEW'
    )
    count = int(result['Attributes']['count'])
    return {
        'statusCode': 200,
        'headers': {'Content-Type': 'application/json'},
        'body': json.dumps({'count': count})
    }

Why this shape matters:

  • Atomic increment. A read-then-write approach (get the item, add one in code, put it back) can lose increments when two requests arrive at the same moment. An ADD update expression asks DynamoDB to do the addition on the server side. Confirm the current behavior of UpdateItem and ADD in the DynamoDB developer guide before you rely on it for accuracy claims.
  • The first call creates the item. ADD creates the attribute if it does not exist, starting from zero. You do not need a separate seeding step for this pattern.
  • Environment variable for the table name. Keeping the name out of code makes the function reusable across environments and keeps the infrastructure template as the single source of names.

Step 3: Choose the API type and route

The AWS API Gateway tutorial for building a serverless CRUD API uses an HTTP API, creates a Lambda function and a DynamoDB table, adds routes, and tests the result. It is a general example, not a recipe for this challenge. It also recommends separate functions per route as a best practice, while using a single function to keep the tutorial simple. For a one-route counter, a single function is reasonable.

For this build:

  • Use an HTTP API, which is the lighter option for a simple Lambda proxy integration. Check current feature differences against REST APIs in the API Gateway documentation if you need features such as usage plans or request validation.
  • Expose GET /visitors (or a similar route). The browser sends a GET request and reads the JSON response.
  • Return a body in the form {"count": 42}, so the front end reads one field.

Step 4: Set least-privilege permissions

The Lambda execution role needs the basic logging permissions that AWS provides through its managed Lambda execution policy, plus one DynamoDB action on one table. For this function, the only data action required is dynamodb:UpdateItem on the table’s ARN. Do not attach a full-access DynamoDB policy to make an error go away. Broad grants work, but they hide the real permission problem and are not a good habit to build in a portfolio project. Write the policy against the table resource, then check CloudWatch logs if the function still fails.

Rank #4
Vilros Raspberry Pi 5 Starter Kit MAX – Official 8GB RAM Pi 5 Board, 128GB Preloaded Micro SD, Case, Power Supply & Cooling – Complete Plug-and-Play Kit for Beginners & Advanced Users
  • 𝗦𝗲𝗮𝗺𝗹𝗲𝘀𝘀 𝗦𝗲𝘁𝘂𝗽 𝘄𝗶𝘁𝗵 𝗣𝗿𝗲-𝗜𝗻𝘀𝘁𝗮𝗹𝗹𝗲𝗱 𝗢𝗦: Start creating right out of the box—our kit arrives with Raspberry Pi OS already on the microSD card, saving you time and effort from day one.
  • 𝗘𝘃𝗲𝗿𝘆𝘁𝗵𝗶𝗻𝗴 𝗬𝗼𝘂 𝗡𝗲𝗲𝗱, 𝗔𝗹𝗹 𝗶𝗻 𝗢𝗻𝗲 𝗕𝗼𝘅: From the case to the power supply and a generous microSD card, we’ve bundled every essential so you can skip the extra shopping and focus on building your dream project.
  • 𝗔𝗱𝘃𝗮𝗻𝗰𝗲𝗱 𝗖𝗼𝗼𝗹𝗶𝗻𝗴 𝗳𝗼𝗿 𝗣𝗲𝗮𝗸 𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲: Enjoy smooth, reliable operation as our whisper-quiet fan and heat sinks work together to keep your Pi running cool—even during intensive tasks.
  • 𝗩𝗲𝗿𝘀𝗮𝘁𝗶𝗹𝗶𝘁𝘆 𝗳𝗼𝗿 𝗔𝗻𝘆 𝗣𝗿𝗼𝗷𝗲𝗰𝘁: Whether it’s coding lessons, retro gaming, smart home setups, or robotics experiments, our kit powers unlimited possibilities, letting you tailor your Pi adventure to your passion.
  • 𝗚𝗹𝗼𝗯𝗮𝗹𝗹𝘆 𝗧𝗿𝘂𝘀𝘁𝗲𝗱 𝗯𝘆 𝗘𝗻𝘁𝗵𝘂𝘀𝗶𝗮𝘀𝘁𝘀 & 𝗘𝗱𝘂𝗰𝗮𝘁𝗼𝗿𝘀: Join a worldwide community of hobbyists, teachers, and first-time makers who rely on Vilros for top-tier quality, comprehensive support, and ongoing inspiration.

Step 5: Handle CORS for the real website origin

Your resume page is served from one origin, such as a CloudFront distribution or a static-site host, and the API lives on another origin (the API Gateway domain). A browser blocks the page from reading the response unless the API says that origin is allowed. This is the CORS check.

  • Configure CORS in the API definition for the exact frontend origin, for example https://your-resume-domain.example, and allow only the methods and headers you use.
  • Avoid a wildcard origin as a production default. AWS’s current general tutorial advises restricting CORS origins in production. A wildcard may be acceptable for a short local test, but tighten it before you finish.
  • Make sure the Lambda response includes the matching headers if your integration returns them directly, and that the API’s CORS settings and the function’s headers do not contradict each other.

The challenge does not give a complete CORS configuration, so verify the exact settings against the current API Gateway documentation for the API type you chose.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Step 6: Deploy with infrastructure as code

The challenge asks you to manage the table, API, function, and permissions as code rather than configuring each one in the console. It recommends AWS SAM and accepts Terraform as an alternative. Both are valid.

Best Value
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
  • Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM)
  • Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
  • CanaKit Premium High-Gloss Raspberry Pi 4 Case with Integrated Fan Mount, CanaKit Low Noise Bearing System Fan
  • CanaKit 3.5A USB-C Raspberry Pi 4 Power Supply (US Plug) with Noise Filter, Set of Heat Sinks, Display Cable - 6 foot (Supports up to 4K60p)
  • CanaKit USB-C PiSwitch (On/Off Power Switch for Raspberry Pi 4)
Tool Strengths for this project Trade-offs
AWS SAM AWS-specific template with short syntax for Lambda, API Gateway, and DynamoDB; the challenge recommends it Works mainly within AWS; you learn an AWS-specific template format
Terraform Reusable skill across clouds and teams; explicit resource graph More verbose for a small serverless stack; you manage provider and state configuration

If you choose SAM, the usual workflow is:

  1. Define the table, function, HTTP API, and CORS settings in template.yaml.
  2. Run sam build to package the function.
  3. Run sam deploy --guided the first time, and choose the region that matches your table.
  4. Copy the API endpoint from the stack outputs and place it in your page’s script.

Check the current SAM documentation for exact flags and template syntax, since these change over time.

Step 7: Connect the page and test

In the resume page script, call the endpoint and write the number into the page. Show a fallback message if the request fails, so the page remains readable:

const COUNTER_URL = 'https://your-api-id.execute-api.your-region.amazonaws.com/visitors';

async function showVisitorCount() {
  const el = document.getElementById('visitor-count');
  try {
    const res = await fetch(COUNTER_URL);
    if (!res.ok) throw new Error('HTTP ' + res.status);
    const data = await res.json();
    el.textContent = data.count;
  } catch (err) {
    el.textContent = 'unavailable';
  }
}

showVisitorCount();

Test in three layers, in this order:

  • Direct endpoint: call the URL with curl or a browser address bar. You should see the JSON body and the count should increase on each call.
  • Table: open the table in the DynamoDB console and confirm the item visits has the expected count.
  • Browser: load the deployed page and check the developer tools network tab for the request and its response headers.

Common failure modes

  • CORS error in the browser console. The endpoint responded, but the origin is not allowed. Compare the page’s exact origin, including scheme and port, with the origin in the API’s CORS configuration.
  • AccessDeniedException in function logs. The execution role lacks dynamodb:UpdateItem on the table ARN. Check the table name and region in the policy.
  • Counter never increases or returns an error. The table name environment variable is missing or misspelled, or the function points at a table in another region.
  • Endpoint returns 404. The route in the page does not match the route in the API definition, or you are calling the stage URL without the stage path.
  • Counter jumps unexpectedly. Your own reloads, browser prefetching, and bots count under a request-counter design. This is expected behavior, not a bug.

To inspect failures, open the Lambda function in the console, find the Monitor view, and open the CloudWatch logs for the function. Console labels move around, so verify the current path before following it step by step.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Costs, limits, and what this build does not prove

AWS’s tutorial states that its own exercise can be completed within the AWS Free Tier. Your actual cost depends on account eligibility, region, and request volume, so do not assume it is free indefinitely. Check the AWS Free Tier page and the pricing pages for each service before you rely on it.

This build counts requests. It does not show unique visitors, and it does not guard against bots. The number is a useful signal for a personal site, not a traffic measurement you should present to an employer as audience data.

Quick Recap

Bestseller No. 1
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM); CanaKit Turbine Black Case for the Raspberry Pi 5
$259.95
Bestseller No. 2
CanaKit Raspberry Pi 5 16GB Starter Kit PRO - Turbine Black (128GB Edition) (16GB RAM)
CanaKit Raspberry Pi 5 16GB Starter Kit PRO - Turbine Black (128GB Edition) (16GB RAM)
Includes Raspberry Pi 5 16GB with 2.4Ghz 64-bit quad-core CPU (16GB RAM); CanaKit Turbine Black Case for the Raspberry Pi 5
$419.99
Bestseller No. 5
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM); Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
$159.99

Learning resources

  • The Cloud Resume Challenge page on AWS for the official requirements.
  • The AWS API Gateway tutorial for building a serverless CRUD API, as a general reference for HTTP APIs, Lambda integration, and DynamoDB.
  • The AWS Lambda getting-started guide for the service basics.
  • The Cloud Resume Challenge book, which AWS links to from the challenge page as further learning. Search for it by that title, since listings, editions, and availability change.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.