JavaScript — the Client You Don't Control
Modern pages rarely reload to talk to the server. The bookshop's "Add to basket" button runs JavaScript that sends a small JSON request to your API and updates the page in place. That code runs on the shopper's machine, where the shopper can read it, change it or skip it entirely.
The rule
Every request is a suggestion; the server decides what is true.
The browser's fetch function sends HTTP requests from JavaScript:
const res = await fetch("/api/books?limit=5");
if (!res.ok) {
throw new Error(`Request failed: ${res.status}`);
}
const books = await res.json();Two details matter to a backend developer:
fetchdoes not reject on 4xx or 5xx. It only rejects when there is no response at all, such as a network failure. A404or500still resolves, withres.okset tofalse. That is why your status codes must be honest: the client's error handling depends on them.- JSON bodies need a header. When sending JSON, the client should say so, and your server should read the body as JSON:
await fetch("/api/orders", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ book_id: 42, quantity: 1 }),
});Now the key point. Anyone can open the browser's developer tools and change this code, or skip the page and send the request with a tool such as curl:
curl -X POST https://bookshop.example/api/orders \
-H "Content-Type: application/json" \
-d '{"book_id": 42, "quantity": -5, "price": 1}'The server cannot tell whether a request came from your page or from someone typing. So treat every field as untrusted input.
The shortcut
For each field in a request body, ask: "What if someone typed any value here by hand?" If a wrong value could cost money, leak data or break things, the server must check it or compute it itself.
List the fields
The page sends
book_id,quantityand, unwisely,price.
This is also why the server's error responses should be clear and specific. The page can show "Only 3 copies left" straight from the server, instead of copying every rule into JavaScript and hoping the two copies never drift apart.
Drills
Answer fast — trust the rule.
A fetch call gets a 500 response. What happens?
The checkout sends {"book_id": 42, "quantity": 1, "price": 1}. What should the server do with price?
Which header tells the server that a request body is JSON?
The page's JavaScript already rejects negative quantities. Should the server check again?
Remember
- Every request is a suggestion; the server decides what is true.
- For each field, ask "what if someone typed this by hand?", then validate it or compute it on the server.
fetchresolves on 4xx and 5xx; honest status codes make the client'sres.okmeaningful.
