September 12, 2026
BACKEND: THE TRUSTED PLACE WHERE PRODUCT RULES ACTUALLY RUN

The frontend from Lesson 45.2 makes a user's job clear. It cannot make the job safe. Anyone can open developer tools, skip the interface, and send requests directly — so every rule that matters must run somewhere the user cannot rewrite. That somewhere is the backend: the code that receives requests, verifies identity and permissions, validates input, applies product rules, calls data and services, records meaningful events, and returns a safe response.
An API route is a contract, not a magic URL
An API route is a named backend entry point that receives a request and returns a response. Name it, type it, and bound it — or an AI will treat every URL as a suggestion. Research Desk needs exactly two to start:
GET /api/brief?ticker=AAPL— returns a defined result. Anyone (including a signed-out visitor) may request a public brief. The backend validates the ticker, reads cache or the approved provider, and returns the brief fields the UI is allowed to show. No request body, no identity required, no writes.POST /api/watchlist— requires a signed-in user and validates its body. The backend verifies the session, validates the submitted ticker and note, checks the caller's ownership of the target watchlist, writes one row, records the event, and returns the saved item or a precise failure.
Each route states its method, its inputs, who may call it, what it returns on success, and what it returns on each failure. That written agreement is the contract the frontend from Lesson 45.2 programs against — and the thing Class 46 will generalize into boundary contracts across the whole architecture.
Client validation helps; server validation protects
Both kinds of validation — checking that input has the expected shape, size, and permitted values before using it — are useful. Only one defends the system:
- Client validation helps the user fix a form sooner. The ticker field rejects
APPLE!!!instantly with "Use a 1–5 letter ticker, such as AAPL." Fast, friendly, and entirely bypassable. - Server validation means the system refuses unsafe or invalid input even when someone bypasses the interface. The backend re-checks the ticker format, length, and allowed values, rejects oversized bodies, strips or refuses unexpected fields, and never passes raw input into a provider query or database command.
Teach this as a law: the frontend's check is courtesy; the backend's check is authority. Every route re-validates everything, because the request arriving at the backend may never have touched your form. Neighborhood Events makes the stakes visible: the browser may warn that an event title is required, but the backend must still reject the empty title, the 50,000-character description, and the owner_id belonging to another organizer — all three sent via a hand-crafted request.
The secret that must move: bad design, then fixed
Bad design: the browser calls the paid research provider directly, carrying your secret key:
browser (+ exposed provider key) → paid provider → browser renders
It works in the demo. It also publishes the key to every visitor (recall Lesson 45.1: View Source is not a vault), lets anyone spend your quota, and returns provider-shaped data the UI must parse five different ways. An unbounded AI task ("add live prices") drifts here by default because it is the shortest path.
Fixed design: the browser calls your application; your application owns the secret:
browser → application backend (owns secret, validates ticker, rate-limits)
→ paid provider → backend returns only the fields the UI needs
The backend validates the ticker, enforces rate limits and quotas, calls the provider with the key from protected server configuration (never the repository, bundle, or log), translates the provider's response into your app's ResearchBrief shape, and returns only the fields the signed-out or signed-in caller may see. The key never crosses the network to a browser. Spending has a ceiling. The frontend parses one shape, not five.
When you brief an AI, state the rule explicitly: "The browser must never call the provider or hold the key. All provider access goes through the named API route, which validates input and returns only the contracted fields." Then review the diff for exactly that: no provider URL or key material in frontend files.
Errors are product behavior — without leaks
A backend distinguishes what went wrong precisely, tells the customer only what helps them act, and keeps the technical detail in the log. Teach this taxonomy as the default for every route:
| Situation | Customer sees | System records |
|---|---|---|
| Invalid input (bad ticker, oversized body) | "Use a 1–5 letter ticker, such as AAPL." | Request ID, route, validation failure class |
| Unauthenticated request (signed-out save attempt) | "Sign in to save companies." | Request ID, route, anonymous caller |
| Forbidden action (saving to someone else's list) | "You can save only to your own watchlist." | Request ID, actor, target owner, deny outcome |
| Not found (unknown ticker or item) | "No brief found for that ticker." | Request ID, lookup key, miss |
| Temporary provider failure | "Fresh data is unavailable; showing the last saved brief." | Request ID, provider result, latency, retry decision |
| Internal fault | "Something went wrong. Try again shortly." | Request ID, error class, stack context — server-side only |
Nothing in the left column contains secrets, stack traces, raw provider errors, database messages, or key fragments. Those live in structured logs with the request ID (Class 51 builds on this), where they help you diagnose without informing an attacker. The status codes behind the table — 400, 401, 403, 404, 429, 500 — guide investigation; the words above are what the person reads.
Practical exercise: the watchlist contract
Draft an API-CONTRACT.md for one route: "save this company to my watchlist" (POST /api/watchlist). Include method, input shape, identity rule, validation rules, success response, expected failure responses (use the taxonomy above), the audit/log event, and test cases — at minimum owner allowed, different user denied, anonymous denied. Then review it against the frontend flow from Lesson 45.2: does the signed-out prompt match the 401 path, does the saved confirmation match the success response, does the provider-down error match what the backend actually returns?
Finish line: API-CONTRACT.md for one route, reviewed against the frontend flow from 45.2.
Verify: hand the contract plus the 45.2 USER-FLOW.md to a reviewer (human or fresh AI session) and ask: "Trace Save from button to database and back. Where is identity checked, where is input re-validated, what does each failure show, and what gets logged?" Every answer should cite a line in one of the two documents.
Common failure mode: a contract that names only success. A route with no stated 401/403/422 behavior has no stated security — and an AI implementing it will invent its own, usually permissive, defaults.
Check your understanding
1. What seven jobs does the backend perform on every request? 2. State the two example route contracts and how they differ in identity rules. 3. Why does client validation never substitute for server validation? 4. In the fixed provider design, where does the secret live and what shape crosses to the browser? 5. Which failure details go to the customer and which stay in the log?
Going deeper: MDN Learn Web Development — server-side concepts behind routes and responses; MDN accessibility guidance — why backend error strings must stay human-readable for assistive technology; Part XI's reference shelf (OWASP Top 10, authentication failures, logging failures) previews the security treatment Classes 47–48 build on these contracts.
ARTICLE DISCUSSION
JOIN THE
CONVERSATION.
Got a question, a take, or a better way to do this? Log in and leave a comment.
