The contract
The frontend and the backend are two independent programs, often written by different people. To understand each other, they agree on a contract: which routes exist, what they receive, and what shape the data they return has.
GET /api/users
→ 200 [ { "id": 1, "name": "Ana" }, { "id": 2, "name": "Luis" } ]
If the backend changes name to fullName, the frontend stops working
even though no frontend file was touched. The contract is fragile:
the two halves depend on respecting exactly the same shapes.
JSON: the common language
Only text travels over HTTP. JSON (JavaScript Object Notation) is the standard format for serializing objects to text and reconstructing them again:
- The backend does
JSON.stringify(data)and sends it as the body. - The frontend receives the text and does
await response.json()to recover it.
That is why you can only send types that JSON understands (objects, arrays, strings,
numbers, booleans, null): no functions and no dates as a Date object.
Status codes
Every HTTP response carries a status code that tells how it went:
- 2xx — success.
200 OK,201 Created(something was created). - 4xx — client error.
400(malformed request),401(not authenticated),403(no permission),404(not found). - 5xx — server error.
500(something failed in the backend).
⚠️ Careful:
fetchdoes NOT throw an error on a 404 or a 500. It only fails if the network goes down. That is why you must checkresponse.ok(true if the status is 2xx) orresponse.statusto detect server errors.
CORS: why the browser blocks other origins
An origin is the combination of protocol + domain + port
(https://myapp.com). For security, the browser applies the same-origin
policy: by default, a page from myapp.com cannot read the response
of an API at another-api.com. This prevents a malicious website from reading data from
another one on your behalf.
CORS (Cross-Origin Resource Sharing) is the way the server grants explicit permission. When the API wants to be consumed from another origin, it responds with a header:
Access-Control-Allow-Origin: https://myapp.com
The browser sees it and allows your code to read the response. If that header is missing, the request goes out, but the browser blocks the read and you will see the typical CORS error in the console.
Key point: CORS is granted by the backend, not the frontend. It is the server that decides which origins can read its data.