Using fetch to make GET, POST, PUT and DELETE requests
Last updated: August 21, 2022.
Fetch is JavaScript’s in-built method (available via the global window object) for making HTTP requests.
It is promise-based: after making a GET, POST, PUT or DELETE request, the Fetch API returns a promise containing the result of the request. So before proceeding with this tutorial, it is a good idea to have a solid understand of how to handle JavaScript promises using .then
and .catch
syntax.
Alternatively, the result of a fetch request can be handled using async-await syntax.
We use promises syntax in the main examples in this tutorial and provide equivalent GET, POST, PUT or DELETE with async-await at the end of the tutorial.
Table of contents
In order that the examples in this tutorial make real API requests, the free endpoints provided by the Reqres service are used. Documentation on how to make valid GET, POST, PUT and DELETE request to their server is available here.
If you do find testing API request on their server useful, please consider making a donation to keep the service free.
Making a fetch GET request
By default, fetch()
makes a GET request. This means that there is less code to write for this type of request than others. The syntax of a fetch GET request is as follows:
fetch('https://example-endpoint.com/api')
And that’s it for the request itself – though we do still need to handle the result!
We can do this using .then
and .catch
syntax.
GET request with result-handling
fetch('https://reqres.in/api/users/2')
.then(res => { /* IF statement checks server response: .catch() does not do this! */
if (res.ok) { console.log("HTTP request successful") }
else { console.log("HTTP request unsuccessful") }
return res
})
.then(res => res.json())
.then(data => console.log(data)) // the data
.catch(error => console.log(error)) // error handling
/* .catch handles a failure with fetch (e.g. syntax error, no internet connection) */
Notice that there are a number of intermediate steps in the .then
chain.
- Check the server response: return
res
to next.then
if successful; log an error otherwise; - Parse the body of the response: from JSON to JS object using
res.json()
; - The body of the response is ready to work with (logged to the console in this example).
If there is any error along that means the fetch request is not able to be made (e.g. typically a syntax or connection error) or the handling of the result produces an error anywhere in the .then chain, the .catch
statement will be executed.
Making a fetch POST or PUT request
To make a POST or PUT request, we need to change fetch's default behavior (making a GET request). This is done by adding an object as a second argument in a fetch call.
The method
property in the object specifies the request method. We can set this to POST
or PUT
.
Then, in a nested object within the headers
property, we specify the content type. This is usually application/json
.
Finally, in the body of the request, we pass in the data to send. If sending a JavaScript object, this must be converted to JSON format by wrapping it in JSON.stringify
.
Here is an example POST/PUT request, excluding any result handling:
fetch('https://reqres.in/api/users', {
method: "POST", // or "PUT" with the url changed to, e.g "https://reqres.in/api/users/2"
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(
{ name: "Captain Anonymous"}
)
});
The result can be handled using .then
and .catch
syntax with an if/else
statement within the first .then
to check the server response. Result handling is identical to a GET request (see above for a detailed description of the process).
POST/PUT with result-handing
fetch('https://reqres.in/api/users', {
method: "POST", // or "PUT" with the url changed to, e.g "https://reqres.in/api/users/2"
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(
{ name: "Capitain Anonymous"}
)
})
.then(res => {
if (res.ok) { console.log("HTTP request successful") }
else { console.log("HTTP request unsuccessful") }
return res
})
.then(res => res.json())
.then(data => console.log(data))
.catch(error => console.log(error))
Making a DELETE request
Making a DELETE request is similar to POST and PUT in that we have to specify this in an object placed in the second argument position in the fetch call (to avoid fetch's the default behavior of a GET request).
Making a DELETE request requires a little less syntax than POST and PUT, though, because we are not passing in any data to be stored on the server:
fetch('https://reqres.in/api/users/2', {
method: "DELETE",
headers: {
'Content-type': 'application/json'
}
})
Assuming the server responds by sending some data, this should be handled using the error-handling steps recommended previously:
DELETE with result-handling
fetch('https://reqres.in/api/users/2', {
method: "DELETE",
headers: {
'Content-type': 'application/json'
}
})
.then(res => {
if (res.ok) { console.log("HTTP request successful") }
else { console.log("HTTP request unsuccessful") }
return res
})
.then(res => res.json())
.then(data => console.log(data))
.catch(error => console.log(error))
Fetch with async-await syntax
The result of a fetch request of any type can also be handled in an asynchronous function, using the await
keyword to pause function processing to wait for the result of any promises:
async function myFetch() {
try {
/* Request */
let res = await fetch('https://reqres.in/api/users/2');
/* Check response */
let resChecked;
if (res.ok) { /* If successful: */
console.log("Request successful");
resChecked = res;
let data = await resChecked.json();
console.log(data);
} else { /* If unsuccessful: */
console.log("Request unsuccessful");
}
} catch (err) {
console.log(err);
}
}
myFetch() // Prints data object containing information about user 2
Summary
JavaScript's Fetch API makes HTTP requests possible in plain JavaScript without the need for an external library or framework.
In this tutorial, we have seen how to make a GET request with minimal syntax (because fetch makes a GET request by default). Passing in an object in the second argument position with different options modifies the fetch request to a POST, PUT or DELETE request with any data to be sent included.
Finally, any type of fetch request can be executed and handled inside an asynchronous function, making the syntax of the request resemble synchronous code.
Happy fetching! 🦴