fetch() & REST APIs
Advanced · 22 min read · ▶ live playground · ✦ checkpoint
fetch() is the browser API that sends an HTTP request and gives your JavaScript a response object. With async/await, the everyday pattern is two awaits: first wait for the response, then wait for the response body to be read as JSON.
This is the first lesson in the course that talks to a real public API. The demos use JSONPlaceholder, a fake API for practice, so you can see live request/response behavior without changing anyone's real data.
GET uses the two-await dance
A GET request reads data from a URL. With fetch, the shape is:
const response = await fetch(url);
const data = await response.json();Those two awaits do different jobs. The first await waits until the browser has a response: status code, headers, and a body stream. The second await reads that body stream and parses it as JSON.
That separation matches the model from 16.1. The server response is not automatically "the data" yet. It is a response object first, and the body still needs to be read in the format you expect.
Run the playground. It fetches posts from JSONPlaceholder, renders whatever titles come back, and shows a visible loading or error state instead of leaving the page silent.
Notice what the UI does before the network finishes: it says loading. If the learner is offline or the API cannot be reached, the page says what failed. That is the minimum honest shape for live data. The deeper rules for checking status codes, timeouts, cancellation, retries, and empty states belong to the next lesson.
REST means resource-shaped URLs plus methods
REST is not a JavaScript library. It is a style of HTTP API design where URLs name resources and methods describe what you want to do with them.
For a posts API, the shape often looks like this:
GET /posts read a list of posts
GET /posts/1 read one post
POST /posts create a new post
PUT /posts/1 replace post 1
DELETE /posts/1 delete post 1The URL names the noun. The method names the action. That makes client code easier to read because the request line carries intent: GET /posts/1 reads one resource; DELETE /posts/1 asks to remove it.
REST APIs commonly send and receive JSON. When your client sends JSON, two pieces need to agree:
headers: { "Content-Type": "application/json" }tells the server the body is JSON text.body: JSON.stringify(value)turns a JavaScript object into JSON text for the wire.
The body is text crossing the network, not a live JavaScript object. The server can parse that text, do its work, and return a response.
Try it — POST, PUT, and DELETE
This playground sends fake write requests to JSONPlaceholder. The service accepts the request shape and returns a practice response, but it does not permanently save, replace, or delete real records.
Choose a method and run it. Then open DevTools Network and inspect the Method, Payload, Request Headers, Status, and Response tabs.
The write request has the same two big phases as GET: wait for the response, then read the response body. The request options are what changed: method, optional headers, and optional body.
JSON.stringify is the bridge from JavaScript value to JSON text. Without it, a plain object body would not become useful wire data. Without the Content-Type header, many servers will not know how to parse the body you sent.
Async/await keeps request code in order
The browser is still doing network work asynchronously, just like the async lessons in Section 12. await pauses only the current async function. It does not freeze the whole page.
That is why the playgrounds can set loading text, start a request, then update the DOM after the response arrives:
show loading
await the response
await the JSON or text body
render success
or render an error from catchThe order reads top to bottom, but the page remains alive between awaits. Buttons can be disabled while the request is in flight, status text can explain what is happening, and the final render can use whatever data actually came back.
For this first fetch lesson, a basic try/catch is enough: it handles network-level failures and bad parsing. Next, you will tighten the contract by checking response.ok, handling 404 honestly, adding timeouts and cancellation, and treating loading, error, and empty states as first-class UI.
Checkpoint
Answer all three to mark this lesson complete