Advanced 25 min read

Building the API Layer: API Gateway and Lambda

By the end of this lesson, you'll be able to:

  • Describe the synchronous request path from a client through API Gateway and Lambda to DynamoDB
  • Justify moving certificate generation onto an asynchronous, queue-based path instead of the synchronous request path
  • Explain why an async worker needs to be idempotent, and what a dead-letter queue is for

Prerequisites: "Designing the Frontend: S3 and CloudFront"

The synchronous path: API Gateway, Lambda, DynamoDB

Most of what this application's API needs to do is straightforwardly synchronous: a learner's browser asks for a lesson's content, or reports that a lesson was completed, and expects a response before moving on. This is exactly what Module 7's API Gateway plus Lambda pattern is for: API Gateway receives the HTTP request and invokes a Lambda function, which does the actual work — reading or writing DynamoDB — and returns a response.

Requirement: handle learner-facing API requests (view a lesson, record progress) without operating always-on servers sized for peak load. Decision: API Gateway routes requests to Lambda functions that read and write DynamoDB. Reason: this combination scales automatically with request volume and has no idle server cost between requests. Alternative: a container-based API (Module 9's ECS/Fargate pattern) running continuously behind a load balancer. Trade-off: Lambda functions have per-invocation constraints (timeout, cold starts) that a long-running container doesn't — reasonable here because these requests are short, but worth stating rather than ignoring.

Certificate generation: why it moves off the request path

Diagram showing the synchronous path from client through API Gateway and Lambda to DynamoDB, and a separate asynchronous path where an event such as a course completion is sent through SQS to a background worker.
The synchronous path is what the learner waits on; the asynchronous path deliberately is not.

This is the module's worked capstone example of asynchronous processing, first introduced in Lesson 1's Project Decision Record: when a learner completes a course, a certificate should be generated (and possibly emailed), but that work — rendering a document, calling an email provider — is slower and not something the learner's "course complete" response should wait on.

Requirement: certificate generation must not block or slow down the learner's course-completion request. Decision: the completion Lambda sends a message to an SQS queue; a separate worker consumes it and generates the certificate. Reason: this decouples a slow, non-critical background task from the fast request/response path the learner is actually waiting on (Module 8's decoupling pattern). Alternative: generate the certificate synchronously inside the same Lambda invocation before responding. Trade-off: the async path is eventually consistent (the certificate isn't ready the instant the response returns) and introduces new failure modes — a message could be processed twice, or a worker could fail — that the synchronous alternative doesn't have.

Making the async path trustworthy: idempotency and dead-letter queues

Moving work onto a queue doesn't remove the responsibility to handle failure — it changes where that responsibility lives. Two concerns matter specifically for this worker:

Idempotency: SQS can, under some conditions, deliver a message more than once. If the worker isn't written to handle that safely — for example, by checking whether a certificate for this learner and course has already been issued before generating another — a retried message could produce a duplicate certificate. An idempotent worker produces the same end result whether it processes a given message once or more than once.

Dead-letter queues: if a message repeatedly fails processing (a malformed record, a downstream error that never clears), it shouldn't retry forever or simply vanish. A dead-letter queue captures messages that failed past a configured retry limit, so they can be investigated instead of silently lost — and a growing dead-letter queue is exactly the kind of thing Lesson 6's monitoring should alert on.

Exercise

Explain, in your own words, what could go wrong if the certificate-generation worker were written without idempotency — that is, if processing the same message twice always generated a brand-new certificate. Then describe one concrete way the worker could check whether a certificate has already been issued before generating another.

Show hint

Think about what SQS's at-least-once delivery guarantee actually implies for a worker that isn't written defensively.

Building the API Layer: API Gateway and Lambda Quiz

1. Why is certificate generation moved onto an SQS-based asynchronous path in this capstone's design?

2. Moving certificate generation onto an asynchronous queue removes the need to handle failures for that work.

3. An idempotent worker produces the same end result whether it processes a given message once or more than once.

4. A message that repeatedly fails processing past a configured retry limit is captured by a dead-letter ______ instead of retrying forever.

Show hint

It is the same messaging primitive this course has used throughout Module 8 and this lesson, just configured as a destination for failed messages.

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

API Gateway and Lambda handle the application's synchronous request/response traffic — reading a lesson, saving progress — while at least one background scenario, certificate generation on course completion, is deliberately moved onto an SQS-based asynchronous path so a slower, non-critical task never blocks the learner's request, at the cost of needing retries, idempotency, and backlog monitoring on that path.