Your first real API
Write the contract first, success shapes, status codes, error bodies, then let the model implement it and review the implementation against the document.
Your first real API
Anyone can return JSON from a route. The engineering is in what you return when it goes wrong, and what the front end does while it waits.
You are specifying, the model is implementing. Write the contract for a small reading-list API before any code exists: GET /api/books returns a list, POST /api/books creates one, GET /api/books/:id returns one or fails. For each route, the success shape, the status codes you will use, and the exact error body. Then let Claude Code or Cursor write the Express handlers, and review them against the document you wrote rather than against your memory of what you asked for.
The error body is the part that matters and the part that gets skipped. Pick one shape and use it everywhere: a machine-readable code your client can branch on, a human-readable message nobody parses, and nothing else. { "error": { "code": "BOOK_NOT_FOUND", "message": "No book with that id" } } is enough. What you must never do is let the message carry meaning: the day someone rewords it for clarity, every client that string-matched on it breaks.
The workbench below is the other half: a front end talking to a stubbed version of that route. It works, on the happy path, on a fast connection, once. Everything the probes ask about is a state the contract has but the client does not.
Loading…
You should now be able to
- Specify an API before any code exists
- Review generated handlers against a written contract
- Give the front end every state the contract implies
Loading…