Making API Requests with Fetch
This tutorial will guide you through the process of making HTTP requests to external APIs using the modern fetch
API in JavaScript. The fetch
API provides a powerful and flexible way to handle network requests.
Understanding the Fetch API
The fetch()
global function initiates a request to a network resource. It returns a Promise
that resolves to the response to that request. The Response
object, in turn, provides a set of methods for inspecting the response headers and body.
Basic GET Request
The simplest way to fetch data is to make a GET request. By default, fetch()
performs a GET request.
Example: Fetching JSON Data
Let's fetch data from a public API (e.g., JSONPlaceholder) to get a list of users.
fetch('https://jsonplaceholder.typicode.com/users')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json(); // Parse the JSON data from the response
})
.then(data => {
console.log('Users:', data);
// You can now work with the 'data' array of users
displayUsers(data);
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
function displayUsers(users) {
const userList = document.createElement('ul');
users.forEach(user => {
const listItem = document.createElement('li');
listItem.textContent = `${user.name} (${user.email})`;
userList.appendChild(listItem);
});
document.getElementById('api-output').appendChild(userList);
}
.then()
method chains asynchronous operations. The first .then()
handles the initial response, and the second .then()
handles the parsed JSON data. The .catch()
block is crucial for handling any errors that occur during the fetch process.
Configuring Requests (POST, Headers, Body)
To perform other HTTP methods like POST, or to send custom headers and data in the request body, you can pass a second argument to fetch()
, which is an options object.
Example: Creating a New Post (POST Request)
This example demonstrates sending data to an API to create a new resource.
const newPost = {
title: 'foo',
body: 'bar',
userId: 1,
};
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST', // Specify the method
headers: {
'Content-Type': 'application/json', // Indicate that we are sending JSON
},
body: JSON.stringify(newPost), // Convert the JavaScript object to a JSON string
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Post created:', data);
document.getElementById('api-output-post').textContent = 'Post created successfully! See console for details.';
})
.catch(error => {
console.error('Error creating post:', error);
document.getElementById('api-output-post').textContent = 'Error creating post. See console for details.';
});
Common Request Options:
method
: The HTTP method (e.g.,'GET'
,'POST'
,'PUT'
,'DELETE'
).headers
: An object containing request headers. Common headers include'Content-Type'
and'Authorization'
.body
: The data to send with the request. This is typically a string (e.g., JSON stringified) for'POST'
and'PUT'
requests.mode
: Controls whether to allow requests to arbitrary origins ('cors'
), prevent certain cross-origin requests ('no-cors'
), or ignore origin restrictions ('no-referrer'
).credentials
: Controls whether to include cookies, authorization headers, or TLS client certificates.
response.ok
property to ensure the request was successful (status code in the 2xx range). It's good practice to also check the specific status code for more granular error handling.
Handling Different Response Types
The Response
object provides methods to parse the response body into various formats:
response.json()
: Parses the body as JSON.response.text()
: Parses the body as plain text.response.blob()
: Parses the body as a Blob (binary data).response.formData()
: Parses the body asFormData
.
.then()
to access the parsed data.
Advanced Topics
The fetch
API supports more advanced configurations, including:
- Request Abort: Using
AbortController
to cancel ongoing requests. - Request Interception: While not directly built into
fetch
, libraries like Axios or custom wrapper functions can achieve this. - Service Workers: For offline capabilities and more sophisticated network request handling.
For more detailed information, please refer to the official MDN Fetch API documentation.