api: Fetch, Explained by a Single HTML File
zubair-trabzada/api turns plain text, JSON, and POST requests into one small lesson in how the Fetch API actually feels.
- The repo teaches fetch as one pipeline with three outputs, not as three unrelated demos.
- Its simplicity is the point, because a single HTML file keeps request flow visible from click to render.
- The code is educationally sharp but production-light, since `innerHTML` and one monolithic script favor clarity over safety and scale.
- Its best comparison is to older XMLHttpRequest code, which feels heavier the moment you trace the same path by hand.
Most Fetch API tutorials stop at the happy path. This repo is more useful because it compares three different outcomes with almost no ceremony: reading raw text, loading local JSON, and posting data to a mock backend. That makes the hidden lesson obvious. Fetch is not one task. It is one interface with three very different shapes.
Why this repo earns its keep
The repository is tiny. The whole thing lives in a single index.html, plus users.json and sample.txt, with Bootstrap pulled from a CDN. That is why it works as a teaching artifact. There is nowhere for the data flow to hide.
It reads like a code-along project, not a product. That is a strength here, because the code shows the complete loop from click to fetch to render without abstractions getting between you and the browser.
Three buttons, three mental models
The UI maps one button to one async function. getText proves that fetch can return a plain string. getUsers shows that the same API can parse local JSON and feed it into map(). addPost closes the loop with a POST request, headers, and JSON.stringify().
fetch("sample.txt").then((r) => r.text());
fetch("users.json").then((r) => r.json());
fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: { "Content-type": "application/json" },
body: JSON.stringify({ title: "Post One", body: "Body", userId: 1 })
});
The important part is the boundary between response headers and response bodies. The first then() gets a Response object. The next step chooses the parser. Text gets .text(), structured data gets .json(), and writes need a request body plus a content type.
- Click a button.
- Call
fetch()against a file or URL. - Choose
text(),json(), or a POST body. - Render the result into
#outputwith a template literal.
What the repo leaves out on purpose
The code leans on innerHTML, which is fine for a sandbox and risky for production. It is fast to write, but it also means any untrusted content could become a problem if the source were malicious. The choice is honest. The repo optimizes for clarity, not hardening.
The rendering pattern is also worth noticing. Template literals act like a poor man's component system, just enough structure to turn raw data into HTML without a framework or build step. For a learning repo, that is the right amount of machinery.
How it compares
| Approach | What it teaches | What it costs |
|---|---|---|
| Fetch API sandbox | The native request pipeline from click to render | Light on structure, but easy to read and copy |
| XMLHttpRequest-era code | The older callback-heavy way of doing the same work | More boilerplate and more mental overhead |
| Framework app | State, components, and declarative rendering | More scalable, but farther from the browser's basics |
That comparison is the point. If you are teaching yourself, or someone else, the native browser primitives, this repo is better than jumping straight to a framework. If you are shipping a larger app, you would keep the same ideas but wrap them in safer rendering, modular files, and stricter data boundaries.