{
    "slug": "fetch_api",
    "term": "Fetch API",
    "category": "javascript",
    "difficulty": "beginner",
    "short": "The browser-native Promise-based API for making HTTP requests — replacing XMLHttpRequest with a cleaner interface supporting streaming, CORS, and request/response objects.",
    "long": "fetch(url, options) returns a Promise that resolves to a Response object as soon as headers arrive — not after the body is fully received. This means a 404 or 500 does not reject the Promise; you must check response.ok or response.status explicitly. The body is a readable stream consumed by methods like response.json(), response.text(), or response.arrayBuffer(), each returning a Promise. The options object controls method, headers, body (string, FormData, Blob, ReadableStream), mode (cors, no-cors, same-origin), credentials (include cookies with 'include'), and signal (AbortController for cancellation). In Node.js, fetch has been native since v18. Common patterns include adding auth headers via a wrapper function, handling errors uniformly, and cancelling in-flight requests when a component unmounts (React) or a new search starts.",
    "aliases": [
        "window.fetch",
        "Fetch API",
        "HTTP fetch",
        "browser fetch"
    ],
    "tags": [
        "javascript",
        "http",
        "api",
        "browser",
        "promises",
        "networking"
    ],
    "misconception": "A non-2xx HTTP response (404, 500) does NOT reject the fetch Promise — the Promise resolves with a Response where response.ok is false. Only network failures (no connection, CORS block) cause rejection.",
    "why_it_matters": "fetch is the standard for browser HTTP requests and Node.js 18+ — understanding response.ok, body streaming, and AbortController is essential for any JS frontend or backend HTTP code.",
    "common_mistakes": [
        "Not checking response.ok — a 500 response resolves the Promise, so error handling is silently skipped.",
        "Calling response.json() without awaiting response first — json() returns a Promise that must also be awaited.",
        "Sending JSON without setting Content-Type: application/json — the server receives the body but cannot parse it.",
        "Not aborting fetch on component unmount — causes state updates on unmounted components and memory leaks in SPAs."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "async_await",
        "js_promises",
        "js_abort_controller",
        "cors",
        "js_async_error_handling"
    ],
    "prerequisites": [
        "async_await",
        "js_promises",
        "http_status_codes"
    ],
    "refs": [
        "https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API",
        "https://developer.mozilla.org/en-US/docs/Web/API/Response/ok"
    ],
    "bad_code": "// Missing response.ok check — silent failure on 4xx/5xx:\nasync function getUser(id) {\n    const res = await fetch(`/api/users/${id}`);\n    return res.json(); // parses error body as if it were success\n}",
    "good_code": "// Check ok, handle errors, support cancellation:\nasync function getUser(id, signal) {\n    const res = await fetch(`/api/users/${id}`, {\n        headers: { Accept: 'application/json' },\n        signal, // AbortController signal\n    });\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return res.json();\n}",
    "example_note": "The bad example calls res.json() unconditionally — a 404 response resolves the Promise and parses the error body as data. The fix checks response.ok and throws, and accepts an AbortSignal for cancellation.",
    "quick_fix": "Add if (!res.ok) throw new Error(`HTTP ${res.status}`) immediately after every await fetch()",
    "severity": "medium",
    "effort": "low",
    "created": "2026-04-10",
    "updated": "2026-04-10",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/fetch_api",
        "html_url": "https://codeclaritylab.com/glossary/fetch_api",
        "json_url": "https://codeclaritylab.com/glossary/fetch_api.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Fetch API](https://codeclaritylab.com/glossary/fetch_api) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/fetch_api"
            }
        }
    }
}