Basic GET Request

Fetching data from an API with proper error handling

The Fetch API provides a modern way to make HTTP requests in the browser. It returns a Promise that resolves to a Response object, which you can then parse to extract the data.

This example demonstrates the fundamental pattern for making GET requests: calling fetch(), checking the response status, and parsing the response body.

Basic Pattern

// Simple GET request with async/await async function fetchData(url) { const response = await fetch(url); // Check if the response was successful if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } // Parse JSON response body const data = await response.json(); return data; } // Usage try { const users = await fetchData('https://api.example.com/users'); console.log(users); } catch (error) { console.error('Failed to fetch:', error.message); }

Key concepts:

  • fetch() returns a Promise that resolves when headers are received (not when the body is complete)
  • response.ok is true for status codes 200-299
  • response.json() returns a Promise that parses the body as JSON
  • Network errors (no connection, DNS failure) reject the Promise
  • HTTP errors (404, 500) do NOT reject — you must check response.ok

With Request Headers

async function fetchWithHeaders(url) { const response = await fetch(url, { method: 'GET', headers: { 'Accept': 'application/json', 'X-Request-ID': crypto.randomUUID() } }); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } return response.json(); }

The second argument to fetch() is an options object where you can specify headers, method, body, credentials, and more. The Accept header tells the server what content types you can handle.

Promise Chain (Alternative)

// Using .then() instead of async/await fetch('https://api.example.com/users') .then(response => { if (!response.ok) { throw new Error(`HTTP ${response.status}`); } return response.json(); }) .then(data => { console.log('Data:', data); }) .catch(error => { console.error('Error:', error.message); });

Both patterns are equivalent. Use async/await for cleaner sequential code, or .then() chains when you need to integrate with existing Promise-based code.

Inspecting the Response

const response = await fetch(url); // Response metadata console.log(response.status); // 200 console.log(response.statusText); // "OK" console.log(response.ok); // true (status 200-299) console.log(response.url); // Final URL (after redirects) console.log(response.redirected); // true if redirected // Response headers console.log(response.headers.get('Content-Type')); console.log(response.headers.get('Content-Length')); // Parse body (can only be read once!) const json = await response.json(); // Parse as JSON // OR const text = await response.text(); // Parse as text // OR const blob = await response.blob(); // Binary data

Important

  • The response body can only be read once. Clone the response if you need to read it multiple times.
  • Always check response.ok before parsing — a 404 response still returns a Response object.
  • Use response.headers.get() to access response headers (some are restricted by CORS).

Try It Live

Request

Click "Fetch" to make a request

Response

Response will appear here