Lab 10: HTTP Requests & Fetch API
Objective
Make HTTP requests in Node.js using the built-in fetch API (Node 18+), handle JSON responses, work with headers and query parameters, and implement basic error handling for network failures.
Background
Every modern application communicates over HTTP — fetching data from APIs, submitting forms, or calling microservices. Node.js 18 introduced a native fetch API identical to the browser's, so the same skills work everywhere. Understanding HTTP methods, status codes, headers, and JSON parsing is foundational for any backend or full-stack developer.
Time
45 minutes
Prerequisites
Lab 09 (Node.js File System) or equivalent
Basic understanding of async/await (Lab 06)
Tools
Node.js 20 LTS
Docker image:
innozverse-js:latest
Lab Instructions
Step 1: Your First Fetch Request
The fetch API returns a Promise that resolves to a Response object. You must call .json() (also a Promise) to parse the body.
💡 Why two awaits?
fetchresolves when the headers arrive. The body streams separately —.json()reads and parses the full body. This lets you inspect status codes before consuming the (potentially large) body.
📸 Verified Output:
Step 2: Query Parameters & Multiple Resources
Build URLs with query strings to filter API responses.
💡 URLSearchParams automatically encodes special characters, handles arrays, and produces a properly formatted query string. Always use it instead of manual string concatenation to avoid injection bugs.
📸 Verified Output:
Step 3: POST Requests — Sending Data
Use POST to create resources. Set the method, headers, and body.
💡 Status 201 vs 200: REST APIs use
201 Createdfor successful POST requests. AlwaysJSON.stringify()your request body and setContent-Type: application/jsonso the server knows how to parse it.
📸 Verified Output:
Step 4: PUT and DELETE — Updating & Removing
💡 PUT vs PATCH:
PUTreplaces the entire resource (you must send all fields).PATCHupdates only the provided fields. Most REST APIs support both.
📸 Verified Output:
Step 5: Error Handling — Network vs HTTP Errors
fetch only throws on network errors (DNS failure, timeout). HTTP 404/500 still resolve — you must check response.ok.
💡 The
response.oktrap is one of the most common bugs in JavaScript.await fetch(badUrl)doesn't throw on 404 — it resolves withresponse.ok === false. Always check it before calling.json().
📸 Verified Output:
Step 6: Request Timeout with AbortController
Node.js fetch has no built-in timeout — use AbortController.
💡 AbortController is a Web API standard — it works in browsers, Node.js, and Deno. The
signalpropagates the abort to any number of concurrent requests. Always clear your timeout to avoid memory leaks.
📸 Verified Output:
Step 7: Parallel Requests with Promise.all
Fetch multiple resources concurrently instead of waiting one-by-one.
💡 Promise.all fires all requests simultaneously and waits for all to complete. Sequential
awaitwaits for each before starting the next — 3× slower for independent requests. UsePromise.allSettledwhen you want results even if some fail.
📸 Verified Output:
Step 8: Build a Mini API Client Class
Combine everything into a reusable HTTP client.
💡 Encapsulating HTTP logic in a class gives you a single place to add auth tokens, logging, retry logic, and base URL management. Real-world API clients (Axios, got, ky) use the same pattern.
📸 Verified Output:
Verification
Expected: User, posts count, and created post ID all print without errors.
Common Mistakes
Not checking response.ok
Always check before calling .json()
Forgetting JSON.stringify(body)
The body must be a string, not an object
Missing Content-Type header on POST
Server won't parse the body correctly
Sequential awaits for independent requests
Use Promise.all for concurrency
No timeout on fetch
Use AbortController with setTimeout
Summary
You can now make all four HTTP methods (GET, POST, PUT, DELETE), handle both network and HTTP errors, add timeouts, run requests in parallel, and wrap it all in a clean API client class. These patterns form the backbone of every Node.js backend and CLI tool.
Further Reading
Last updated
