Foundations · Lesson 3/8

APIs & REST — How Software Talks

40 min 2 exercises 1 quiz Graded labs: 1

What you'll learn

  • What an API is (the waiter analogy)
  • HTTP methods (GET, POST, PUT, DELETE) and status codes
  • What makes an API RESTful
  • You'll build a mini request router in code

The restaurant waiter 🧑‍🍳

You sit at a table (the frontend). You don't march into the kitchen (the database) and cook — you tell the waiter what you want, and they bring it back. An API (Application Programming Interface) is that waiter: a well-defined menu of requests one program can make to another.

REST is the most common style for web APIs. It maps actions to HTTP methods on resources (things, named by URL):

GET    /users        → read the list of users
GET    /users/5      → read user #5
POST   /users        → create a new user (data in the body)
PUT    /users/5      → update user #5
DELETE /users/5      → delete user #5

See the pattern? Same URL, different method = different action. That's the elegance of REST — it reuses HTTP's own verbs for CRUD.

Every response carries a status code — a 3-digit summary:

  • 2xx = success. 200 OK, 201 Created
  • 4xx = you (the client) messed up. 400 Bad Request, 401 Unauthorized, 404 Not Found
  • 5xx = the server messed up. 500 Internal Server Error

Data usually travels as JSON — the universal format for structured data:

{ "id": 5, "name": "Sara", "email": "sara@mail.com" }

So a full exchange: frontend sends GET /users/5, server replies 200 with that JSON. Learn to read this and you can talk to any web service on earth.

Exercise 1

Build the heart of a REST router. Write route(method, path) that returns the right status code:

  • GET + "/users" → 200
  • POST + "/users" → 201 (created)
  • anything else → 404 (not found)

Query parameters and pagination 📄

Not every request is "give me everything." A URL can carry extra details after a ? — these are query parameters:

GET /users?role=admin&sort=name
              ↑            ↑
        filter by role   sort by name

Each key=value pair (joined by &) tells the server exactly what slice of data you want, without needing a different URL for every combination.

The most common use is pagination. Imagine /posts has 2 million rows — returning all of them in one response would be huge and slow, for both the server and the client. Instead, APIs return one page at a time:

GET /posts?page=1&limit=20   → posts 1-20
GET /posts?page=2&limit=20   → posts 21-40

The server uses limit (how many items) and page (which chunk) to slice the data — in SQL terms, this maps almost directly to LIMIT 20 OFFSET 20. A well-designed paginated response also tells the client how to get more:

{ "data": [ /* 20 posts */ ], "page": 2, "totalPages": 100000 }

Query parameters are for filtering, sorting, and paging — optional details about how to fetch a resource. Contrast this with the URL path (/users/5), which identifies which resource. Mixing the two up is a common beginner mistake: the resource's identity goes in the path, everything else goes in the query string.

Exercise 2

Build a pagination slicer. Write paginate(items, page, limit) that returns the correct slice of an array for a given page — page numbers start at 1.

Example: paginate([1,2,3,4,5], 1, 2) → [1,2]; paginate([1,2,3,4,5], 2, 2) → [3,4].

Real-world case study: this platform's own API 🔍

This isn't abstract — the very login system behind this site is a small REST API. Its backend (a Cloudflare Worker, in worker/src/index.ts) exposes real REST-style endpoints such as an OAuth callback, a GET endpoint returning the logged-in user's profile, and GET/POST endpoints for progress and bookmarks — each one reads the HTTP method and path, checks an Authorization header for a valid token, and returns JSON with an appropriate status code.

For example, a request for the current user's stats runs a query like:

GET /api/me   (with header: Authorization: Bearer <token>)
→ 200 { "username": "...", "progress": {...}, "bookmarks": {...} }

If the token is missing or invalid, the same endpoint returns 401 Unauthorized instead — exactly the status-code discipline from this lesson. This is a real, deployed, minimal REST API doing exactly what you just learned: HTTP methods mapped to actions, resources identified by path, and status codes communicating success or failure — running right now, powering the account system on the page you're reading this lesson on.

Lab exercise 1

JavaScript (Node.js)Graded in Code Lab

Validate before you trust. A POST /users endpoint must reject bad input with 400 and a precise reason. Each line of standard input is one request body (JSON text). For each line print one result:

  • 400 body when the text is not valid JSON or is not a JSON object
  • otherwise check the fields in this order and report the first problem as 400 <field>:
    1. name must be a non-empty string after trimming
    2. email must be a string with exactly one @, text on both sides, and a . in the part after the @
    3. age is optional, but when present it must be an integer from 13 to 120
  • 201 when everything is valid

Blank lines are skipped.

Visible tests (4)
  • A valid request and a missing name
  • Reports the first failing field in order
  • Age is optional but strict
  • Not JSON, not an object
Example run
Input
{"name":"Amal","email":"amal@example.com","age":30}
{"email":"a@b.co"}
Expected output
201
400 name
Starter code
const fs = require("fs");

function validate(line) {
  let body;
  try {
    body = JSON.parse(line);
  } catch {
    return "400 body";
  }
  // TODO 1: return "400 body" unless body is a plain object (not null, not an array)
  // TODO 2: name: non-empty string after trim()   -> "400 name"
  // TODO 3: email: string, exactly one "@", text on both sides, a "." after the "@"  -> "400 email"

More lines in Code Lab: 8

Try in Code Lab

Hints and instant feedback are in Code Lab. Optional practice: it does not block finishing the lesson.

JavaScript and Python also run in your browser without an account; other languages use the secure server runner and need a free account.

Quick quiz

Question 1 of 4

Which HTTP method creates a new resource?

Question 2 of 4

A 404 status code means…

Question 3 of 4

What format do most REST APIs use for data?

Question 4 of 4

The core REST idea is…

Summary

  • An API is a waiter: a defined way for programs to request things
  • REST maps HTTP methods (GET/POST/PUT/DELETE) to resources
  • Status codes: 2xx success, 4xx client error, 5xx server error; data is JSON
  • You built a mini REST router

Next: Auth & Security — how the server knows who is making each request and whether they're allowed.