AWS Builder Center
Beginner guide to Serverless Cloud Applications on AWS

Beginner guide to Serverless Cloud Applications on AWS

Learn fundamental concepts for building a serverless backend on AWS with Amazon API Gateway, AWS Lambda, and Amazon DynamoDB through a beginner-friendly ecommerce example.

Series: New To AWS Beginners Guide (12 articles)

  1. …
  2. 12
    Beginner guide to Serverless Cloud Applications on AWS This article
Developer Relations Engineer
By Rob Dahal, Developer Advocate at Amazon Web Services (AWS)
Maya finds a Northstar Daypack on our website for $59. Later, she opens our mobile app. The same bag costs $79.
Which price should she trust? She might abandon her cart, contact support, or decide to shop somewhere else. Our small business now has a customer problem caused by an application design decision: each frontend shipped with its own copy of the product catalog.
Meet I Get Da Bag, our fictional bag shop. We will follow Maya from browsing to checkout, then ask what changes when she returns and more customers arrive. Each problem introduces a computing concept before we connect it to an AWS service. The central design is a shared serverless backend using Amazon API Gateway, AWS Lambda, and Amazon DynamoDB.
This article accompanies AWS Workshop Part One: Cloud Fundamentals, November 3, 2026, at 1:00 PM EST, with 40 minutes of teaching and 20 minutes of Q&A. You only need a little familiarity with JavaScript to follow the examples. Part Two, on November 10 at 1:00 PM EST, turns the catalog request path into a hands-on build.

Get the storefront online

Our first version runs on a laptop. It has product photos, names, descriptions, ratings, reviews, a search box, and a cart. It reads hardcoded product data from a JSON file. JSON is a text format for structured data; the frontend is the interface the customer sees and interacts with.

Figure 1. These illustrative screens and fictional products give us customer actions to design around.
The business needs a dependable public address. Managed hosting publishes the web application, HTTPS encrypts connections, and a content delivery network, or CDN, delivers content from locations closer to customers. AWS Amplify Hosting supplies these capabilities and can build and deploy updates from a connected Git repository. The team can publish the shop without keeping the founder's laptop running.  Amplify Hosting overview ,  Amplify custom domains and HTTPS 
That solves reachability. It does not turn the web app's JSON file and the mobile app's JSON file into one shared catalog.

Give both apps the same catalog

The website's $59 price and the mobile app's $79 price come from different copies of the data. Releasing a new website does not update an already-installed mobile app. The business needs product changes to reach both experiences without two frontend releases.
The general solution is a shared API: an agreed interface through which both apps request data or actions from the same backend. The backend owns the authoritative catalog. Frontends display its responses.

Figure 2. A shared backend removes the need to maintain two independent product catalogs. Caching and older responses still need explicit freshness rules.
Before choosing services, sketch the jobs:
Ask about Maya's experience
General capability
How can both apps request the same product information?
An API
Where do product names, brands, prices, and stock live after a process stops?
A database
What returns only Northstar bags or checks whether three bags are available?
Backend logic
Where do the actual product photo files belong?
Object storage

Figure 3. Start with responsibilities. Service names come after the requirements.
Imagine Maya adds three Daypacks to her cart. If only two remain, the shop should not promise her three. A cart can express what she wants; trusted backend logic decides what the business can accept. That distinction will matter at checkout.

Choose how the backend runs

Compute means the resources that execute our code. We could run the whole application on a virtual server: an Amazon EC2 instance. A web server process receives requests while the instance is running, including after periods with no shoppers. We choose capacity and maintain the operating system and application software. EC2 Auto Scaling can add or remove instances; EC2 is a scalable option.  EC2 overview ,  EC2 security responsibilities ,  EC2 Auto Scaling 
Alternatively, an incoming request can invoke a handler with AWS Lambda. A handler is the function that processes the event. For the handler-based Lambda Event Functions used here, the standard on-demand model means AWS manages the execution environments and their underlying servers. An environment can be reused; preparing a new one can add startup latency, called a cold start. Serverless still uses servers. It changes who operates them and how our code executes.  Lambda execution environment lifecycle 

Figure 4. Both designs can serve an API. The tradeoffs include operational responsibility, workload shape, latency, and cost.
Business situation
Design worth considering
Quiet overnight, a promotion spike, then quiet again; short product requests; a small team
On-demand Lambda reduces the need to operate server capacity
An existing server application, custom operating-system needs, or continuously running work
EC2 provides direct control over the server environment
For I Get Da Bag, short requests and uneven traffic make serverless a useful starting choice. This is a workload decision, not a claim that it always costs less. Compare the full system's cost, latency, limits, and operational needs.  AWS compute decision guide 

Turn customer actions into API requests

Maya does not think in routes. She opens the shop, selects a brand, taps a bag, and places an order. Our API gives those actions a shared language.
Maya's action
HTTP request
What the backend should return or do
Opens the homepage
 GET /products 
Return a page of product summaries
Selects Northstar
 GET /products?brand=Northstar 
Return a page of products for that exact brand
Opens the Daypack
 GET /products/bag-101 
Return details for that product
Submits her cart
 POST /orders 
Validate the request and attempt to create an order

Figure 5. The frontend turns customer actions into requests. The backend returns data and outcomes; the frontend decides how to display them.
GET reads data. POST requests an action such as creating an order. A route combines an HTTP method and path. In  GET /products/{id} , the changing  id  is a path parameter. In  ?brand=Northstar ,  brand  is a query parameter: an option attached to the list request, not a separate API Gateway route. This example is an exact-brand filter, not full-text search.  HTTP API routes 
Amazon API Gateway provides the managed entry point. We use its HTTP API option to match routes and invoke Lambda integrations. It does not decide our stock policy or store product prices; those responsibilities belong elsewhere.  API Gateway HTTP APIs 

Let Lambda apply the application's rules

For the homepage, our logic lists products. For the brand selection, it lists matching products. For a product tap, it looks up one identifier. Here is the small piece of a handler that explains Maya's Daypack request:
// Teaching excerpt for GET /products/{id}
export const handler = async (event) => {
const id = event.pathParameters.id;
const product = await getProductById(id);
return {
statusCode: product ? 200 : 404,
body: JSON.stringify(product ?? { message: "Not found" }),
};
};
An invocation is one execution of the handler. API Gateway supplies the request information in  event . Our application helper,  getProductById , retrieves the record. The response uses 200 for success or 404 for a missing product. The helper is code we write, not a built-in Lambda command. A complete handler also validates input and handles failures.  HTTP API Lambda integration 

Figure 6. Follow one request from the customer's action to the data and back. Permissions and logs support the path; they are not extra HTTP hops.
The companion examples separate request handling from data access. A local demonstration uses a small fixture so you can inspect all three GET behaviors without an AWS account. The SDK-backed entry point implements detail reads and exact-brand queries. Plain  GET /products  returns 501, not implemented, until a homepage access pattern is supplied. A fixture is useful for learning; it is not the durable catalog we need in the deployed shop.

Keep product records outside the worker

Maya opens another bag. The next request may run in a different Lambda environment. If product changes lived only in the first worker's memory, another worker would not reliably see them.
Stateless processing means a request can work without depending on a previous worker's memory. Persistence means the data survives beyond that request or process. Our general solution is a shared database. Amazon DynamoDB stores key-value and document data in tables. A product is an item, and its fields are attributes.  DynamoDB overview 
In our simple table,  productId  is the string partition key and the complete primary key:
{
"productId": "bag-101",
"name": "Northstar Daypack",
"brand": "Northstar",
"priceCents": 5900,
"currency": "USD",
"stock": 2,
"imageKey": "products/bag-101.jpg"
}
Prices use integer cents:  5900  means $59.00. The key lets our helper request that product directly rather than examine every bag:
// Inside our data helper; db is a DynamoDBDocumentClient.
const { Item } = await db.send(new GetCommand({
TableName: process.env.PRODUCTS_TABLE,
Key: { productId: id },
ConsistentRead: true,
}));
 GetCommand  is the AWS SDK for JavaScript v3 wrapper for  GetItem .  ConsistentRead: true  requests a strongly consistent table read. The default is an eventually consistent read, which can briefly return an older value. A strong read still does not reserve inventory or make a later write safe from competing shoppers.  DynamoDB item operations ,  SDK v3 DynamoDB examples 
The homepage is a different access pattern: a question we need the database to answer. A production catalog needs a deliberate way to list products, such as category or collection queries, and pagination so each response returns a bounded page. We do not replace that design with an unbounded table scan. Later, we will design the exact-brand query.

Store photos as objects

Maya needs a photo as well as a product record. Object storage holds file contents. In Amazon S3, an object lives in a bucket and has a key, such as  products/bag-101.jpg . The product record stores the reference; S3 stores the image bytes.  Amazon S3 overview 

Figure 7. The catalog response and the photo have separate delivery paths. Lambda does not need to relay every image byte.
For public product photos, we can configure Amazon CloudFront to serve and cache images while its authorized origin access keeps the S3 bucket private. This is separate from Amplify Hosting's delivery of our web application.  CloudFront access to an S3 origin 

Treat the cart as a request rather than a promise

Maya adds three Daypacks. Updating a cart in the browser does not automatically invoke Lambda; our frontend decides when to call the API. When she chooses Place order, the app sends a request like this:
POST /orders
Content-Type: application/json
Idempotency-Key: checkout-attempt-123

{"items":[{"productId":"bag-101","quantity":3}]}
The backend must validate quantities, load trusted prices, and check availability. It should not accept a price edited in the browser. A small piece of the business logic looks like this:
// Inside an illustrative validator, after validating the request shape.
const product = await getProductById(item.productId);
if (!product) throw new Error("Product not found");
if (!Number.isInteger(item.quantity) || item.quantity < 1)
throw new Error("Choose a positive whole-number quantity");
if (item.quantity > product.stock)
throw new Error("Not enough stock");
const lineTotalCents = product.priceCents * item.quantity;
Three available $59 bags would total $177 before tax and shipping. Our record has only two, so this request must be resolved rather than accepted as three. The backend can return an availability conflict and let Maya change her cart.
This read-and-check code explains the rule; it does not reserve stock. Two shoppers could both read the same remaining quantity. A real order flow needs an atomic conditional inventory update, durable order creation, secure guest-session ownership, and payment-provider coordination. Atomic means the protected change succeeds as one unit. DynamoDB conditional writes and transactions are tools for designing that part.  Conditional writes ,  DynamoDB transactions 
The companion POST demonstration returns a validation and pricing plan, explicitly not an accepted or paid order. The idempotency header above also needs a backend implementation; a header alone prevents nothing.

Give the function access and make failures visible

A line connecting Lambda to DynamoDB is not a permission. AWS Identity and Access Management, or IAM, controls access to AWS resources. An execution role gives the function permissions for its job. Our product-detail handler needs  dynamodb:GetItem  on the intended table and permission to write logs. An order writer or brand-query handler needs different permissions. Least privilege means narrowing actions and resources to the job.  IAM best practices 
These are the permissions we intend to grant, not a claim about every project’s defaults. Check effective permissions, including managed role behavior in the new AWS experience.
If Maya says, “The bag page is broken,” Amazon CloudWatch helps us investigate. A log records an event, such as a missing product with a request ID. A metric measures behavior over time, such as latency or failures. Lambda sends logs to CloudWatch Logs when its role permits it. Record useful clues without passwords, tokens, or payment details.  Lambda logging 
Monitor the customer's HTTP result as well as function execution. A handler that catches an error and returns HTTP 500 can complete successfully from Lambda's perspective. API Gateway's  5xx  metric and Lambda's  Errors  metric answer different questions.  HTTP API metrics ,  Lambda metrics 

Explore the next customer problems

We now have the core request path. The next topics are directions to explore as requirements grow, not a checklist to implement on day one. Accounts add new features; the other scenarios reveal performance and reliability concerns that become harder to ignore as more people shop.

Returning customers need protected account access

Maya returns on her phone. She wants order history, delivery updates, and the status of a refund. For our shop, a lasting customer account connects those experiences across devices. Authentication establishes who signed in. Authorization decides which records and actions that person may access.
Amazon Cognito user pools provide a customer directory, sign-up, and sign-in. After login, Maya's app receives a signed, temporary access token.  Cognito user pools 
// accessToken comes from the completed sign-in flow.
await fetch(`${apiBase}/me/orders`, {
headers: { Authorization: `Bearer ${accessToken}` },
});

Figure 8. A valid sign-in does not grant access to every order or every refund action.
Configure an HTTP API JWT authorizer for the intended issuer and audience, with appropriate route scopes. A JWT is a signed token carrying identity and permission information; a scope is a permission label. Lambda then uses the verified  sub  customer identifier to fetch Maya's records or check ownership. It must not trust a customer ID supplied by the browser. Maya may request an eligible refund; approving it is a separate action with separate authorization.  HTTP API JWT authorizers 
For a browser app, use a supported sign-in library, authorization code with PKCE to protect the sign-in code exchange, and an app client without a secret. Guest checkout also needs protected access; knowing an order number should not expose someone's order.  Cognito app clients ,  Authorization code and PKCE 

Popular products need fewer repeated reads

A creator shares the Daypack. Many shoppers request the same public details. Repeating identical backend work can increase latency and load.
A cache stores a reusable response. A hit finds a valid copy; a miss fetches one. We could explicitly configure CloudFront caching for eligible public catalog reads. Its cache key must distinguish relevant values, including brand and page options, so different requests do not accidentally reuse the same result. Time to live, or TTL, limits freshness.  CloudFront cache policies 

Figure 9. Cache public catalog responses deliberately. Keep private order history out of this shared cache.
The tradeoff is staleness: Maya might briefly see an older price. Checkout still checks authoritative price and stock. HTTP APIs do not have API Gateway's built-in REST API response cache; this CloudFront layer is an additional configuration.  HTTP API and REST API comparison 

Brand selection needs the right database index

Maya selects Northstar. Reading every product and discarding other brands wastes work. An index organizes data for a lookup we expect to perform.
A DynamoDB global secondary index, or GSI, can use  brand  as its partition key and  productId  as its sort key. The backend queries the Northstar group:
// BrandIndex must exist with the keys and projected fields we need.
const page = await db.send(new QueryCommand({
TableName: process.env.PRODUCTS_TABLE,
IndexName: "BrandIndex",
KeyConditionExpression: "#brand = :brand",
ExpressionAttributeNames: { "#brand": "brand" },
ExpressionAttributeValues: { ":brand": "Northstar" },
Limit: 20,
}));

Figure 10. Design the index around the question. Filtering results after reading them does not remove the reading work.
The example returns one page. Continue with  LastEvaluatedKey  when present. A GSI adds storage and update work, and supports eventually consistent reads: recent changes can take time to appear. An exact-brand index is not a full search engine.  DynamoDB GSIs ,  Query filter behavior 

A repeated order attempt needs the same outcome

Maya taps Place order. The network stalls, so she retries. Did the operation fail, or did only its response get lost?
Idempotency means repeating the same intended operation does not create another effect. The app generates one attempt key and reuses it for retries. The backend scopes it to Maya or her protected guest session, coordinates work in progress, and records the completed outcome. The same key with different cart contents must be rejected; a genuinely new order needs a new key.

Figure 11. A request identifier becomes useful for retries only when the backend persistently enforces its meaning.
Powertools for AWS Lambda provides an idempotency utility with persistent storage. Choose the key, payload validation, and retention window carefully. Coordinate payment-provider idempotency and recovery from partial failures too; wrapping a handler does not automatically make every external side effect safe.  Powertools idempotency 

A flash sale needs controlled concurrency and deferred work

Maya and two other shoppers submit requests together. Three executions are in progress: that is concurrency, not requests per second. Lambda can scale execution environments, within limits. Reserved concurrency reserves capacity for a function and caps its simultaneous work, which can protect a downstream dependency. A fourth synchronous request beyond an illustrative cap of three may be throttled; it does not automatically join a queue. Provisioned concurrency instead prepares environments to reduce startup delay and has an additional cost.  Lambda concurrency controls 
Now suppose Maya's order is accepted, but sending the confirmation email is slow. She should be able to see her order number while that follow-up task waits. A queue stores work for processing later. Amazon SQS holds messages; a Lambda worker can process them in the background. The customer-facing order path and the email worker now have different jobs.

Figure 12. A limit controls active work. A queue stores deferred work. Neither substitutes for correct stock and payment rules.
The handoff must be reliable. If we save the order and crash before sending its email task, the task is lost. A transactional outbox design saves the order and an outgoing task together, then reliably relays the task to the queue.  Transactional outbox pattern 
Messages can be delivered more than once, so consumers need duplicate-safe processing. The visibility timeout temporarily hides a received message while it is processed. Configure retries, partial batch failure handling, and a dead-letter queue for tasks that repeatedly fail.  Lambda with SQS ,  SQS failure handling 

Build a backend you can explain and recreate

A teammate should not need to reconstruct the shop from a series of console clicks. Infrastructure as code, or IaC, describes resources and connections in version-controlled source. AWS CDK can define the API, functions, tables, and permissions; AWS CloudFormation manages them as a stack. Review changes, deploy, test a request, and plan cleanup. Retained data and other remaining resources need checking after deletion.  AWS CDK overview 
Kiro can help turn customer requirements into a design, tasks, and code. Agent Toolkit for AWS adds AWS-specific skills and tools to supported coding assistants. Kiro connects directly to the AWS MCP Server; MCP is the protocol connecting an assistant to external capabilities. Documentation lookup helps explain a design, while authenticated operations require the intended AWS identity and permissions.  Kiro specs ,  Agent Toolkit overview ,  Connection options 

Figure 13. Use the assistant to make the design easier to inspect, test, and explain.
Try a prompt grounded in Maya's behavior:
Help me build the catalog backend for I Get Da Bag. Explain GET /products, an exact-brand filter, and GET /products/{id}. Show how API Gateway invokes Lambda and how DynamoDB answers each access pattern. Separate local fixtures from real persistence. Propose tests for found, missing, and invalid products. Confirm the target account or project, Region, permissions, cost drivers, and cleanup plan. Show the infrastructure changes before deployment, and help me inspect the result afterward.
Before creating resources, identify your account or project, Region, sign-in identity, and cost controls. An AWS Region is a geographic area where resources run. In the new AWS experience, follow your project's AWS Settings and designated Region; existing or advanced accounts have a different identity setup. Use temporary access for daily development and protect sign-in with multi-factor authentication, or MFA. Check the current plan, credit balance and expiry. Where available, project spend limits can pause resources; ordinary budget alerts are notifications, not a universal spending cap.  AWS signup comparison ,  Project spend limits ,  AWS Budgets 
For the new experience, AWS Settings provides a project-specific agent setup prompt under Create and manage cloud infrastructure → Use your AWS credentials with AI coding tools. Follow that official flow and confirm the target before making changes. The companion beginner setup guide expands these steps.  Connect an AI coding tool 

Bring one customer action to Part Two

Can you follow Maya's tap all the way through the system? The app requests a product. API Gateway receives it. Lambda runs the logic. DynamoDB supplies the record. The app displays the result and loads the image through its delivery path.
Now change the customer problem. She wants only Northstar bags, her own order history, or a safe retry after a timeout. Each change gives you a reason to investigate the next concept.
Join AWS Workshop Part Two: Build and Deploy Your Own Serverless API, November 10, 2026, at 1:00 PM EST. We will build a focused catalog API, deploy it, call it, inspect a request, and clean up. Accounts, checkout, caching, and queues are extension paths rather than promises that the core lab implements a complete store.
Before then, complete the setup checklist and choose one customer action you want to explain. Sketch its request path. Use your coding assistant to challenge the sketch, and check its answers against the behavior your customer needs.
I Get Da Bag, Maya, products, prices, reviews, and traffic scenarios are fictional teaching examples. The companion code includes local demonstrations and SDK examples, not a deployed checkout system. Service guidance reviewed November 3, 2026; consult the linked documentation for current setup details.

Series: New To AWS Beginners Guide (12 articles)

  1. …
  2. 12
    Beginner guide to Serverless Cloud Applications on AWS This article
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article