REST Design, Auth & Status Codes
Lesson 5 of 5 · View course roadmap
Learn the idea
Good APIs follow REST conventions so developers can guess how they work:
- Nouns, not verbs, in URLs:
GET /api/coursesnot/api/getCourses - Plural resources with ids:
/api/courses/42/lessons/3 - Method = action: same URL, different verbs do different things
- Meaningful status codes + a consistent JSON error shape:
{"error": "..."} - Version your API:
/api/v1/...
Auth in practice: API keys (simple, per-app), Bearer tokens / JWT (per-user, expiring), OAuth (delegated, "Sign in with…"). Never put secrets in code — read them from environment variables (.env files, exactly like this project does).
Where you'll use this
Good REST design is why Stripe's API is famously pleasant and legacy SOAP APIs are famously not. API design interviews for backend roles are this lesson, spoken aloud.
Common mistakes
- Verbs in URLs (
/getUser,/createOrder) — the HTTP method already is the verb. - Inconsistent error shapes — every error should return the same JSON structure so clients can handle all of them with one code path.
- Breaking existing clients with changes — that's what /v1/ → /v2/ versioning is for.
- Committing API keys to git — they get scraped from public repos within minutes. Environment variables, always.
Pro tip
Before designing anything, skim the Stripe or GitHub API docs for 15 minutes — you'll absorb naming, pagination, error and versioning conventions from the best in the business.
Try it yourself
The lesson example is loaded and ready — press Run, then change something and run it again. Breaking it is part of learning. Want a clean slate? Tap “New blank”.
Output appears here…
Pass the challenge +35 XP
Write route_action(method, path) returning: "list" for GET /items, "create" for POST /items, "detail" for GET /items/<anything>, and "unknown" otherwise. Print the four calls in the starter.
list create detail unknown
path.startswith("/items/") catches detail routes.
def route_action(method, path):
if method == "GET" and path == "/items":
return "list"
if method == "POST" and path == "/items":
return "create"
if method == "GET" and path.startswith("/items/"):
return "detail"
return "unknown"
print(route_action("GET", "/items"))
print(route_action("POST", "/items"))
print(route_action("GET", "/items/9"))
print(route_action("PATCH", "/other"))
Run your code to check it…
Check your understanding
Your notes (saved on this device)
Tip: use ← and → to move between lessons, ⌘K to search everything.