Using fetch to make GET, POST, PUT and DELETE requests

Reading Time: 4 minutes 🕑

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

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.

  1. Check the server response: return res to next .then if successful; log an error otherwise;
  2. Parse the body of the response: from JSON to JS object using res.json();
  3. 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! 🦴