← The 16-day journey
Chapter 03 · Backend, with Claude Code

Building the part nobody sees

The frontend from Chapter 2 is a beautiful shop with nothing behind the counter. Now we build the brain — the backend from Chapter 1 that checks the rules and talks to the database. Same Claude Code workflow, one big difference: this part has no screens, so you will learn to judge it a new way.

Small shapes entering through a single gate into a corridor of orderly checkpoint frames and emerging transformed on the far side.
One door in, checkpoints in sequence, one answer out. That is a backend.

01A program with no face

Everything you built in Chapter 2 you could see — click a button, watch the screen. The backend has no screen. It is a program that sits on a server, listens for requests, and answers them. Its only face is its behaviour: what comes back when you ask, how fast, and what it refuses to do.

This changes how you verify work. In Chapter 2, Claude’s “eyes” were a browser taking screenshots. For a backend, the eyes are different: you judge it by sending requests and reading the answers, and by automated tests that do this for you hundreds of times a second. Hold that thought — it shapes this whole chapter.

02What backend work is actually made of

Like the frontend’s seven jobs, the backend has its own:

  • Routes (endpoints)the items on the API menu from Chapter 1 — “POST /login”, “GET /notices”. Each one is a door with a name.
  • Validationchecking every incoming request at the door. Chapter 1's iron rule — the frontend is never trusted — is enforced here.
  • Business rulesthe actual thinking: who can post a notice, what happens when it's reported, what a valid order is.
  • Talking to the databasereading and writing the memory — always through one layer, never scattered everywhere.
  • Authtwo questions on every request: who are you? and are you allowed to do this?
  • Errors and status codesanswering failure honestly — the right code and a clear message, not a crash.
  • Logsthe backend's diary — what happened and when, so at 2 a.m. you can find out why something broke.

03Language: still the secondary decision

Backends are written in Java, Python, C#, Go — and JavaScript. For this journey we use Node.js with Express and TypeScript, for one very practical reason: it is the same language as your frontend. One language means every review skill you built in Chapter 2 carries straight over, and Claude moves between both sides of the wire without switching costumes. If your college taught Java or Python — nothing here is wasted. Routes, validation, services, auth, tests: every concept transfers; only the spelling changes.

04Setup — the memory file, backend edition

The workflow is the one you already know: a folder, a CLAUDE.md, a docs/ directory, and the loop. Only the contents change — backend rules are about trust and safety, not pixels.

CLAUDE.md — backend edition
# CLAUDE.md

API for the college notice-board app. Node.js + Express + TypeScript.
The frontend from ../notice-board-web consumes this API.

## Commands
- npm run dev    -> start on localhost:4000
- npm run test   -> run all tests (must pass before every commit)
- npm run lint   -> must pass, no warnings

## Structure
- src/routes/     -> one file per resource; routes stay THIN
- src/services/   -> the business rules; all thinking happens here
- src/db/         -> the ONLY place that touches the database
- src/middleware/ -> auth and validation, applied at the door
- docs/api-contract.md is the source of truth. Change it FIRST.

## Rules
- Validate every request body at the door. Trust nothing from the client.
- Routes never contain business logic; services never send responses.
- Never log passwords, tokens, or personal data.
- Every endpoint gets a test for its success case and its failure cases.

05The API contract is the real spec

In Chapter 2 I made you write docs/api-contract.md and build the frontend against mock data. Here is the payoff: that same file is now the construction plan for the backend. The contract sits between both sides like a signed agreement — the frontend was built expecting these exact requests and responses, so the backend’s job is simply to honour them.

docs/api-contract.md — one entry
## POST /notices          (auth required)
Creates a notice.

Request body:
  { "title": string (3-100 chars), "body": string (max 2000) }

Responses:
  201  { "id": string, "title": string, "body": string,
         "authorId": string, "createdAt": string }
  400  { "error": "what exactly was wrong with the input" }
  401  { "error": "log in first" }

Your instruction to Claude becomes: “Read docs/api-contract.md. Implement POST /notices exactly as written, with validation and tests for the 201, 400 and 401 cases.” Precise input, precise output. And when frontend and backend disagree later — the contract file decides who is wrong. This is how real teams with separate frontend and backend engineers stay sane, and you are learning it as a student.

06The anatomy of one request

Inside the backend, every request walks the same corridor. Learn this shape once and every backend you ever open — in any language — becomes readable:

Diagram · the corridor every request walks
requestfrom thefrontendauthwho are you?validatereject garbageservicethe rules thinkdb layerone door onlydatabase401 — log in first400 — bad input, here's whyresponse — 200/201 + JSON, the right status code
Auth first, validate second, then think, then remember. Routes stay thin; services think; the db layer is the only door.

The order matters and is worth saying out loud. Auth comes first — no point validating a request from someone who shouldn’t be here at all. Validation second — reject garbage at the door, politely, with a 400 and a reason. Only then does the service do the thinking, the db layer do the remembering, and the route send back an answer with the right status code. Routes stay thin — they receive and respond. Services think. The db layer is the only door to the database. Three sentences that will keep every backend you build clean.

07Status codes and errors — answering honestly

Status codes are the API’s facial expressions, and you only need six to start. 200 — done, here you go. 201 — done, and I created something new. 400 — your request made no sense (their mistake). 401 — I don’t know who you are, log in. 404 — that thing doesn’t exist. 500 — I broke, and it’s my fault, not yours.

The professional habit hiding in there: 4xx codes blame the client, 5xx codes blame the server — and an honest backend never sends a 500 for what is really a 400. One more rule that sounds small and isn’t: error messages should say what went wrong (“title must be 3–100 characters”) without leaking how the system works inside. Helpful outside, quiet about the machinery.

08Auth in plain words

Auth is two different questions wearing one name. Authentication: who are you? You prove it once — email and password — and the backend hands you a token: a long signed string your frontend attaches to every later request. Think of the stamped wristband at an event: show it at every gate instead of showing your ticket again. Authorisation: fine, you’re in — but are you allowed to do this? A student can post a notice; only an admin can delete someone else’s. Same wristband, different colours.

And one rule you must never break, even in a toy project: passwords are never stored as-is. They are run through a one-way scrambler (called hashing) so that even if the database leaks, no one recovers the real passwords. Claude will do this correctly if your CLAUDE.md demands it — and you will check the diff, because now you know what to look for.

09Tests — the backend’s screenshots

Here is where the Chapter 2 loop earns its keep. The verify step for a backend is not a screenshot — it is a test: a small program that sends a request to your endpoint and checks the answer. “POST /notices with a good body returns 201. With a one-letter title, 400. Without a token, 401.” Written once, they run in seconds, forever, on every change.

With Claude, tests stop being homework. It writes them alongside the endpoint, runs them, and fixes its own failures before you even look — if your CLAUDE.md demands tests, which yours now does. Your job is to review what is tested: the rules from the contract, especially the failure cases. A test suite that only checks the happy path is a seatbelt made of paper.

the backend loop — what changes from Chapter 2
Specify   -> the endpoint's entry in docs/api-contract.md
Plan      -> Claude proposes: route + service + validation + tests
Build     -> it writes the files, runs lint and the build
Verify    -> npm run test  (and curl the endpoint yourself — feel it)
Review    -> read the diff; check validation, status codes, no leaks
Commit    -> git, then /clear and next endpoint

That curl in the verify step is a tiny terminal tool that sends one request by hand — the backend developer’s way of pressing the button. Ask Claude to show you; sending your first hand-written request and reading the raw JSON answer is this chapter’s version of the magic moment.

10Folder structure — the corridor, as folders

the structure — mirrors the request's path
notice-board-api/
  CLAUDE.md
  docs/
    api-contract.md      # THE source of truth (shared with the frontend)
    architecture.md
  src/
    routes/
      notices.ts         # thin: receive, call service, respond
      auth.ts
    services/
      notices.service.ts # the rules live here
      auth.service.ts
    middleware/
      auth.ts            # the wristband check
      validate.ts        # the door check
    db/
      index.ts           # the ONLY file that touches the database
    lib/
      types.ts           # shared shapes — mirror the contract
  tests/
    notices.test.ts      # one test file per resource
  package.json

Compare it with the diagram above — the folders are the corridor. That is the point: when structure mirrors the journey of a request, both you and Claude always know where a change belongs. “Fix the validation on notices” touches exactly one predictable place.

11What you must still learn by hand, backend edition

Same warning as Chapter 2, sharper consequences. A sloppy frontend looks ugly; a sloppy backend leaks data and loses money. So: read every diff that touches auth or validation twice — those are the load-bearing walls. Learn to read a stack trace calmly (the error’s family tree — it tells you exactly where things died). And practise explaining the corridor — auth, validate, think, remember, respond — because “design an API for X” is one of the most common interview questions there is, and it is answered with exactly what you now know.

12Do this today

Take the api-contract.md you wrote in Chapter 2. Create the backend folder, write the CLAUDE.md from section 04, and run the loop endpoint by endpoint: GET /notices first (no auth — easiest), then POST /notices, then login. Curl each one. Watch the tests pass. Then the graduation moment: delete the mock data from your frontend and point it at your real API. When the notice you post from the browser comes back from your own backend — that is the full loop from Chapter 1, built by you, twice over.

One thing is still missing: your notices vanish every time the backend restarts, because they live in its temporary memory. You know from Chapter 1 exactly what is supposed to fix that. Next chapter: the database.