Published:

Fetch API - A Lightweight Fetch Wrapper to Simplify HTTP Requests

This is a quick post to show how to create a fetch wrapper - a lightweight wrapper around the native browser fetch() function to simplify the code for making HTTP requests.

The fetch wrapper below contains methods for making get, post, put and delete HTTP requests, it automatically handles the parsing of JSON data from responses, and throws an error if the HTTP response is not successful (!response.ok).

Example HTTP POST request with fetch directly

This is the code for making an HTTP POST request that includes error handling using the native fetch() function directly.

const requestOptions = {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ title: 'Native Fetch POST Request Example' })
};
fetch('https://jsonplaceholder.typicode.com/posts', requestOptions)
    .then(async response => {
        const data = await response.json();

        // check for error response
        if (!response.ok) {
            // get error message from body or default to response status
            const error = (data && data.message) || response.status;
            return Promise.reject(error);
        }

        console.log('Success!', data);
    })
    .catch(error => {
        console.error('There was an error!', error);
    });


Example HTTP POST request with the fetch wrapper

This is the code for making the same request as above using the fetchWrapper.

fetchWrapper.post('https://jsonplaceholder.typicode.com/posts', { title: 'Fetch Wrapper POST Request Example' })
    .then(data => console.log('Success!', data))
    .catch(error => console.error('There was an error!', error));


The Fetch Wrapper

This is all the code for the fetch wrapper, it includes methods for the main HTTP request types GET, POST, PUT and DELETE, and can be easily extended to support other request types if required.

The handleResponse() helper function parses the response body text into a JSON object, it uses the response.text() method instead of response.json() to prevent an error if the response body is empty.

The handleResponse() helper function also throws an error if the HTTP response is not successful (!response.ok), the native fetch() function will throw an error for network errors but not for HTTP errors such as 4xx or 5xx responses. For HTTP errors we can check the response.ok property to see if the request failed and reject the promise ourselves by calling return Promise.reject(error);. This approach means that both types of failed requests - network errors and http errors - can be handled by a single catch() block.

For an example of this fetch wrapper being used with React see React + Formik - Master Details CRUD Example.

export const fetchWrapper = {
    get,
    post,
    put,
    delete: _delete
};

function get(url) {
    const requestOptions = {
        method: 'GET'
    };
    return fetch(url, requestOptions).then(handleResponse);
}

function post(url, body) {
    const requestOptions = {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
    };
    return fetch(url, requestOptions).then(handleResponse);
}

function put(url, body) {
    const requestOptions = {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
    };
    return fetch(url, requestOptions).then(handleResponse);    
}

// prefixed with underscored because delete is a reserved word in javascript
function _delete(url) {
    const requestOptions = {
        method: 'DELETE'
    };
    return fetch(url, requestOptions).then(handleResponse);
}

// helper functions

function handleResponse(response) {
    return response.text().then(text => {
        const data = text && JSON.parse(text);
        
        if (!response.ok) {
            const error = (data && data.message) || response.statusText;
            return Promise.reject(error);
        }

        return data;
    });
}

 

Subscribe or Follow Me For Updates

Subscribe to my YouTube channel or follow me on Twitter or GitHub to be notified when I post new content.

 


Supported by