# Chapter 36: Practical Case One: Building an API Gateway with Auth and Rate Limiting from Scratch

## Lesson objectives

- **O1** Can distinguish the risk or responsibility covered by authentication, rate limiting and observability (artifact: API-gateway layered map)
  - Evidence: The API-gateway layered map separately defines the coverage of authentication, rate limiting and observability
- **O2** Can construct a API-gateway layered map with a check method and evidence for each stratum (artifact: API-gateway layered map)
  - Evidence: Every stratum in the API-gateway layered map states a check method, owner and passing evidence
- **O3** Can verify authentication, rate limiting and observability separately for an API gateway (artifact: API-gateway layered map)
  - Evidence: The artifact records the test method, observed output and unverified scope for all three control planes

## Learning paths

- **Novice**: Chapter transfer task: Can verify authentication, rate limiting and observability separately for an API gateway. Use the diagram's strata relationship to complete the first evidence item in the API-gateway layered map, then check each owner and decision rule.
- **Experienced**: Apply this task to a current project before reading the explanation: Can verify authentication, rate limiting and observability separately for an API gateway. Submit the API-gateway layered map, then check the relationship type, missing evidence and authority boundary.

## Teaching diagram

- **Required artifact**: API-gateway layered map
- **Diagram kind**: gateway-architecture
- **Relationship semantics**: The three strata organise distinct coverage and form a joint defence; they are not sequential steps, and each gap requires its own repair.
- **Core concepts**: authentication · rate limiting · observability

![Chapter 36 teaching diagram for the API-gateway layered map](/learning/diagrams/en/chapter-36.svg)

Inspect the coverage and evidence in each stratum of the API-gateway layered map; visual height does not imply process order.

The API-gateway layered map is drawn as three stacked strata for authentication, rate limiting and observability. The stack separates coverage areas and shows a joint defence, not execution order or maturity. Every stratum requires its own check method and evidence.

> **Adapted public course.** Concepts, procedures and examples are adapted from the internal textbook. Case sizes, timings, improvement figures and target thresholds are illustrative, not site delivery results or universal standards. Verify tools, platforms and skills in your environment. Prompts do not grant permissions and retry counts do not authorize recovery. Preserve work and verify targets, sharing and external-state effects first.

## Lesson explanation

### 36.1 Breakdown and Blueprint Design

Scenario: Build the core logic of an API gateway with authentication (Auth) and rate-limiting (Rate Limit) mechanisms from scratch.

This scenario condenses the most classic methodology question in AI-assisted programming: placing these two cross-cutting concerns -- "authentication" and "rate limiting" -- in the correct architectural positions while keeping them decoupled. It is the best practice drillground for the "structural milestones" and "rebuild at first sign of chaos" discipline.

Phase One: Breakdown (systematic dimensionality reduction).

Following the "systematic dimensionality reduction" principle from Chapter 10, we build a dependency tree to clarify the absolute sequence of implementation:

<!-- code-example:chapter-36-E1 mode:reference -->
> **Example type: reference.** Reference fragment; it is not guaranteed to run alone. Adapt it to the lesson context, project versions and real interfaces, then validate with observed output.
```text
Phase One (lay the foundation): JWT Auth Middleware (core, independent, do first)
Phase Two (build load-bearing walls): Rate-Limit Middleware (depends on Phase One infrastructure)
Phase Three (run utilities): Route Binding and Middleware Assembly (horizontal integration)
```

Key Decision: Phase One's milestone is only "complete the JWT Auth middleware" -- absolutely do not touch rate-limiting logic yet. Split the two cross-cutting concerns into two independent structural milestones, each verifiable on its own.

Blueprint Design Points (written into CONTEXT.md):

- Tech Stack Constraints: Node.js + Express (or equivalent framework); JWT parsing library; rate-limiting driver with reserved interface;
- Data Models: No database needed (middleware is pure logic), but must define Token payload structure (user_id, exp, iat) and the data contract for rate-limit counters;
- API Contracts: Middleware inputs (request object) and outputs (request object + authenticated user context / 429 response); custom exception formats (401 AppError, 429 RateLimitError);
- Milestone Dependency Tree: M1 JWT Auth Middleware → M2 Rate-Limit Middleware → M3 Gateway Route Assembly and Integration Acceptance.

Directional Tip: Before having the AI write any code, hand it the CONTEXT.md and acceptance criteria first. An example of the M1 acceptance criteria:

<!-- code-example:chapter-36-E2 mode:reference -->
> **Example type: reference.** Reference fragment; it is not guaranteed to run alone. Adapt it to the lesson context, project versions and real interfaces, then validate with observed output.
```text
Acceptance Criteria (M1: JWT Auth Middleware):
1. Parse the Bearer Token in the Authorization header;
2. Verify signature and expiration time; return 401 if expired;
3. On success, inject user_id into the request context;
4. All failure cases uniformly throw a 401 AppError;
5. Sensitive fields in the Token payload (e.g., secret key) must not leak into logs.
```

### 36.2 Milestone Progression and Acceptance

Milestone M1: JWT Auth Middleware.

- Issue Instruction: Feed the acceptance criteria to the AI as hard constraints (acceptance-driven development);
- Coding: AI generates the middleware code;
- Acceptance: Functional test (test requests with valid/expired/forged tokens one by one), architectural test (does the middleware maintain single responsibility, does it sneak in unnecessary libraries?), security test (no hardcoded secrets, Token payload doesn't leak sensitive info);
- Conclusion: PASS → `git commit` to solidify → update CONTEXT.md (record M1 completion, confirm API contract) → clear session.

Milestone M2: Rate-Limit Middleware.

- Issue Instruction: Clarify technical constraint -- "the rate-limiting logic must remain as an independent middleware, never coupled with the auth middleware";
- Coding: AI generates the rate-limiting logic;
- Acceptance: Functional test (requests exceeding the threshold within a time window return 429), architectural test (still decoupled?), boundary test (concurrent scenarios, counter reset);
- Conclusion: PASS → commit → update blueprint.

Milestone M3: Route Assembly and Integration Acceptance.

- Mount both middlewares onto the gateway route in the correct order;
- Integration Acceptance: Authentication failure short-circuits before entering rate-limiting logic; rate-limit counting treats authenticated and unauthenticated requests consistently; end-to-end test of the full chain passes.

### 36.3 A Deliberate Architecture Drift: Identify → Elevate → Rebuild

Deliberately cause an architecture drift (this is the full version of the Chapter 10 practical drill):

How the drift occurs: Issue a deliberately vague instruction to the AI -- "add rate-limiting functionality" (without providing any technical constraints). The AI will very likely determine that "the simplest way to implement this": hardcode a memory-based rate-limiting logic directly into the current auth middleware file. Auth and rate-limiting become tightly coupled, and the file begins to bloat.

Identification Signals (danger radar alarm):

- Foundation tampering: The AI modified the already-solidified auth middleware file (M1, an already-accepted milestone);
- Size out of control: A single middleware file rapidly bloats.

Elevated Instruction (First Step Correction): Don't blame the details; point out the structural flaw in architect language:

> "Your recent implementation hardcodes the rate-limiting logic inside the auth middleware, breaking the Single Responsibility Principle and coupling two cross-cutting concerns. Please extract the rate-limiting logic into a separate middleware to maintain module decoupling."

Stop Implementation (Second Step): If the AI falls into the "self-consistency trap" -- introducing an abnormally large and incompatible third-party rate-control framework to "decouple," or even breaking the original route-binding mechanism so the gateway won't start -- stop immediately after two consecutive failed corrections. Do not debate a third time.

Complete Rebuild (Third Step):

<!-- code-example:chapter-36-E3 mode:runnable -->
> **Example type: runnable.** Runnable command. Directory: this course repository root; version: the project-locked toolchain; expected: exit code 0 plus repository or test status. On failure, inspect the directory, dependencies and command output; never treat failure as a pass.
```bash
## Inspect the branch and working tree without performing recovery
git status --short
git log --oneline -5
```

Protect needed tracked, untracked, and ignored files, then verify the full M1 target hash and choose a recovery path in Section 10.4: consider reset only on a personal unshared branch; use revert for shared erroneous commits. A stash is not an undo and does not protect ignored files by default; Git does not restore databases or external systems. After recovery, rerun M1 acceptance to verify authentication before implementing rate limiting.

After Rebuild: Rewrite the Prompt with detailed blueprint instructions for the rate-limiting mechanism -- "use an in-memory counter to implement sliding-window rate limiting, maintain middleware-isolated state, return a unified 429 format". Then clear the now-contaminated conversation (`/clear`) and feed the new blueprint to a fresh AI instance.

Result: The new round of code generation precisely implements the functionality while maintaining perfect architectural elegance.

### Retrospective: Mindset at Each Decision Point

| Decision Point | Mindset |
|--------|------|
| Why only auth in Phase One, absolutely no rate-limiting? | Systematic dimensionality reduction -- lay foundations when laying foundations; don't let the AI leap across levels |
| Why write acceptance criteria before coding? | Acceptance-driven development -- acceptance criteria are the best instruction and also your red line |
| Why escalate architecturally instead of micromanaging after a drift? | Point out structural flaws in architect language; give the AI one or two chances to self-correct |
- Decide from inspection evidence. Stop and diagnose repeated failures; preserve work and confirm targets and authorization before recovery. Retry counts do not automatically trigger a rebuild.
| Why choose controlled recovery followed by rebuilding? | Compare total costs including protection and verification per Section 7.5, and recover per Section 10.4 |
| Why restart the conversation after rebuilding? | Cut off the AI's historical negative memories; start fresh with clean context |

---

## Independent exercise

Use fictional or authorized deidentified material. Answer independently before revealing the reference. Save `chapter-36.md` with versions, decisions, evidence and gaps.

Define authentication, rate-limit and cache milestones for a fictional gateway. Test unauthorized access, excess requests and cross-user cache leakage and plan recovery.

<!-- chapter-artifact-requirement -->
### Required chapter artifact: API-gateway layered map

The submission for this independent exercise must contain the evidence below. The existing prompts supply content but do not replace these acceptance items.

- O1: The API-gateway layered map separately defines the coverage of authentication, rate limiting and observability
- O2: Every stratum in the API-gateway layered map states a check method, owner and passing evidence
- O3: The artifact records the test method, observed output and unverified scope for all three control planes

<details>
<summary>Reveal reference feedback (answer first)</summary>

## Reference feedback

Define identity and errors before rate limits and caching. Reject unauthorized requests, return contractual 429 responses and isolate cache identity. Test concurrency and dependency faults separately. Diagnose drift using evidence instead of manufacturing incidents, preserving shared history and external state.

### Self-review and next steps

Check whether your decision is explicit, evidence reproducible and unknowns honestly recorded. The reference illustrates one defensible approach, not a unique answer. Seek peer review for alternatives with equivalent evidence. Mark unsupported parts unfinished and revisit the corresponding step.

</details>

## Sources and boundaries

Registered sources support only the external claims used here. The API-gateway layered map, example numbers and exercise scenario are internal instructional design and require project-specific validation.

- [GitHub Actions documentation](https://docs.github.com/en/actions) — GitHub, 2026-09-17. Repository workflows can automate build, test and continuous-integration tasks.
- [MDN Web Security](https://developer.mozilla.org/en-US/docs/Web/Security) — Mozilla, 2026-09-17. Web systems need explicit protection boundaries for common attack surfaces and browser security mechanisms.
