Learn to use fetch() in API call Easily !

Today we are going to explore the fetch function in API calls and get to know about different methods (such as GET, POST, PUT and DELETE), Call Authentication and Interceptor.

XMLHttpRequest (XHR) was used before fetch() was introduced to make http requests. An XMLHttpRequest would need two listeners to be set to handle the success and error cases and a call to open() and send(). It was more complex to understand and implement.

A sample snapshot of XHR code performing asynchronious GET request.

 //Create the XHR Object
    let xhr = new XMLHttpRequest;
    //Call the open function, GET-type of request, url, true-asynchronous
    xhr.open('GET', 'http://www.example.com/users', true)
    //call the onload 
    xhr.onload = function() 
        {
            //check if the status is 200(means everything is okay)
            if (this.status === 200) 
                {
                    //return server response as an object with JSON.parse
                    console.log(JSON.parse(this.responseText));
        }
                }
    //call send
    xhr.send();

What is fetch() method ?

The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch() method that provides an easy and logical way to fetch resources asynchronously across the network.

Fetch Method Figure
Api Call

fetch() allows us to make network requests similar to XMLHttpRequest. The main difference is that the Fetch API uses Promises, which enables a simpler and cleaner API, avoiding callback hell and having to remember the complex API of XMLHttpRequest.

The fetch method only has one mandatory argument, which is the URL of the resource we wish to fetch

What are the different methods used by fetch() ?

Some most popular methods used by fetch to make an HTTP request to an API are :

  • GET
  • POST
  • PUT
  • DELETE

GET

GET requests are the most common and widely used methods in APIs and websites. The GET method is used to retreive data from the server at the specified resource. For example, say we have an API with a ‘/users’ endpoint. Making a GET request to that endpoint should return a list of all available users.

Since a GET request is only requesting data and not modifying any resource, it is considered as a safe and idempotent method.

GET is often the default method in HTTP clients

//set the specific API URL
const url = 'http://www.example.com/tasks';

//function to make API Call
const getFetch = async (url) => {
  const response = await fetch(url);  
  //convert response to Json format
  const myJson = await response.json();
  // return the response
  return myJson ;
}

POST

The POST method sends data to the server and creates a new resource. The resource it creates is subordinate to some other parent resource. When a new resource is posted to the parent, the API service will automatically associate the new resource by assigning it an ID (new resource URI).

In short, this method is used to create a new data entry.

In web services, POST requests are used to send data to the API sever to create or udpate a resource. The data sent to the server is stored in the request body of the HTTP request.

The simplest example is a contact form on a website. When we fill out the inputs in a form and hit Send, that data is put in the response body of the request and sent to the server. This may be JSON, XML, or query parameters (there’s plenty of other formats, but these are the most common).

It’s worth noting that a POST request is non-idempotent. It mutates data on the backend server (by creating or updating a resource), as opposed to a GET request which does not change any data. 

//set the specific API URL
const url = 'http://www.example.com/tasks';
//initialize the data to be posted
const data = {
    userId: 11,
    id: 2,
    title: “coding task”,
    completed: false
  }

//function to make API Call
const postFetch = async (url,data) => (
  const response = await fetch(url, {
      method: 'POST',
      headers: {
        //type of data
        'Content-Type': 'application/json'
      },
      //data to be posted on server
      body: JSON.stringify(data)
    });
  //convert response to Json format
  const myJson = await response.json();
  //return the response
  return myJson ;
}

NOTE : we needed to pass in the request method, body, and headers. We did not pass these in earlier for the GET method because by default these fields are configured for the GET request, but we need to specify them for all other types of requests. In the body, we assign values to the resource’s properties, stringified. Note that we do not need to assign a URI — the API will do that for us. As you can see from the response, the API assigns an id to the newly created resource.

PUT

The PUT method is most often used to update an existing resource. If we want to update a specific resource (which comes with a specific URI), we can call the PUT method to that resource URI with the request body containing the complete new version of the resource we are trying to update.

Similar to POST, PUT requests are used to send data to the API to create or update a resource. The difference is that PUT requests are idempotent. That is, calling the same PUT request multiple times will always produce the same result. In contrast, calling a POST request repeatedly may have side effects of creating the same resource multiple times.

//set the specific API URL
const url = 'http://www.example.com/tasks/5';
//initialize the data 
  const data = {
    userId: 1,
    id: 5,
    title: “hello task”,
    completed: false
  }

//function to make API Call
const putFetch = async (url,data) => {
  const response = await fetch(url, {
     method: ‘PUT’,
    //data to be updated on server
    body: JSON.stringify(data),
    headers: {
      //type of data
      “Content-type”: “application/json; charset=UTF-8”
    }
  });
  //convert response to Json format
  const myJson = await response.json();
  //return the response
  return myJson;
}

DELETE

The DELETE method is exactly as it sounds, i.e. it delete the resource at the specified URI. This method is one of the more common in RESTful APIs so it’s good to know how it works.

If a new user is created with a POST request to /users, and it can be retrieved with a GET request to /users/{{userid}}, then making a DELETE request to /users/{{userid}} will completely remove that user.

//set the specific API URL
const url = 'http://www.example.com/tasks/3';

//function to make API Call
const deleteFetch = async (url) => (
  const response = await fetch(url, {
    method: ‘DELETE’
    });
  //convert response to Json format
  const myJson = await response.json();
  //return the response
  return myJson ;
}

How to pass authentication parameters ?

We can add the authentication parameters to fetch function and authenticate our API call by adding them as an header to fetch function. It increases the security and authenticity of an API call.

Most of the API’s need access permission to make use of those API’s, so user/developer has to register themselves and accept their terms & conditions, in return they get the login credentials which they may pass to header to get access to that API.

//set the specific API URL
const url = 'http://www.example.com/tasks';

//function to make get API Call with authentication
const authFetch = async (url) => {
  const response = await fetch(url, {
    headers: {
      //type of data
      “Content-type”: “application/json; charset=UTF-8”,
     //adding authentication to API call
      "Authenticate": "Basic user:password"
     //replace user and password with the original credentials
    }
  });
  //convert response to Json format
  const myJson = response.json();
  //return the response
  return myJson;
}

Using Interceptors in fetch()

We can intercept requests or responses before they are handled by then or catch.

Interceptors helps in performing some required tasks such as changing or manipulating url, logging the data , adding tokens to header, etc before and after making an API call. It automatically invoked in all API calls and we don’t need to explicitly intercept each and every API call.

Api call

It enhances the API call and provide more features to make API call more efficient and effective. In order to make use of the interceptor we have to install a package named fetch-intercept in our project.

To install fetch-intercept package we may run one of these command in the terminal.

yarn add fetch-intercept --save
//OR
npm install fetch-intercept --save

We may make use of intercept on request as well as response through the below code fragment and make our API call more smooth and errorless.

import fetchIntercept from 'fetch-intercept';
 
const registerIntercept = fetchIntercept.register({
    request: function (url, config) {
        // Modify the url or config here
        console.log(url);
        return [url, config];
    },
 
    requestError: function (error) {
        // Called when an error occured during another 'request' interceptor call
        return Promise.reject(error);
    },
 
    response: function (response) {
        // Modify or log the reponse object
        console.log(response);
        return response;
    },
 
    responseError: function (error) {
        // Handle a fetch error
        return Promise.reject(error);
    }
});

Conclusion

Anyone looking to build a complete application must know how to query a database. Almost all applications would require you to fetch and store data from a database. These request methods are more than enough for a fully functional application. Javascript’s new Fetch API is extremely simple to use. Whether you’ve worked with APIs before, it is easy to pick up or adapt to. Nonetheless, the fundamental understanding of each of these requests, authentication and interceptors would well equip you to be adaptable to other kinds of HTTP request methods and helps in making safe, smooth and efficient API call.

Leave a Comment

Your email address will not be published. Required fields are marked *