AceDevHub
Modern PatternsFree

fetch and JSON APIs

Call HTTP APIs with fetch — methods, headers, bodies, JSON parsing, and the error-handling patterns production frontends use.

IntermediateFreeHTTP

Every React page and Node script eventually talks HTTP. fetch is the browser-native Promise-based API; Node 18+ includes the same global. Unlike axios, fetch does not throw on 404 — you must check response.ok and parse JSON yourself. Understanding request lifecycle (headers, body, CORS, credentials) separates engineers who debug network tabs from those who blame "CORS magic."

GET requests and reading JSON

fetch(url) defaults to GET. The returned Promise resolves when response headers arrive — status may still be 4xx/5xx. Call response.json() for JSON bodies (also async). Text, blob, and arrayBuffer exist for other content types. Always validate status before treating body as success data.

fetch-get.js
Loading editor…

POST with JSON body

POST/PUT/PATCH send data in the body. JSON APIs set Content-Type: application/json and stringify objects with JSON.stringify. Server frameworks parse the body back into objects. Idempotency-Key headers protect duplicate submits on payment and form endpoints — retry-safe design beyond this lesson's scope but worth knowing exists.

fetch-post.js
Loading editor…

Building a small API client

Apps wrap fetch in one module: base URL from env, shared headers, consistent error type, envelope unwrapping. AceDevHub web uses lib/api/server.ts and client.ts patterns — direct Fastify calls, no Next.js proxy. Centralizing fetch avoids copy-pasting credentials and error handling in every component.

api-client.js
Loading editor…

AbortController — cancel in-flight requests

Pass signal from AbortController to fetch options. Call controller.abort() when the user navigates away or types a new search query — prevents race conditions where stale responses overwrite fresh UI state.

abort-fetch.js
Loading editor…

Browser fetch and Node fetch (undici) share the same Response API in modern stacks. Always separate network errors (catch) from HTTP semantic errors (status check). Centralize JSON parsing in one client module so auth headers, retry, and abort logic stay consistent across AceDevHub web and admin surfaces.

Parsing and content types

Not every response is JSON — HTML error pages and empty 204 bodies break response.json(). Check Content-Type or use response.text() first when integrating legacy APIs. Centralize parsing in your api() helper so one place handles text vs json vs blob downloads.


  1. 1fetch resolves on network; check response.ok for HTTP errors
  2. 2JSON APIs: Content-Type header + JSON.stringify body
  3. 3Wrap fetch in one client — credentials, errors, envelope
  4. 4AbortController cancels stale requests
  5. 5Next lesson: debounce and throttle