Fetch request and response interceptor

Add a request and response interceptor method to fetch that can be used to monitor each request and response.

Example

const requestInterceptor = (requestArguments) => {
 console.log("Before request");
}

const responseInterceptor = (response) => {
 console.log("After response");
}

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => console.log(json))

// "Before request"  
// "After response"  
/* 
{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}
*/

Axios, one of the most popular library for making network calls comes with interceptors axios.interceptor.request and axios.interceptor.response which can be used to monitor and perform actions before any request is made and after every response is received.

For example, you can add a response interceptor and monitor if the server is giving 401 unauthorized, then log out the user from the application and reset the state.

We can implement the same by overriding the existing fetch method. All we have to do is store the original fetch method in a variable and override it.

Create two methods on the Window object (so that it is globally available), requestInterceptor and responseInterceptor.

Before each request, pass the arguments to requestInterceptor and get the updated value from it, passing it further to the original fetch method.

Similarly, after each response, pass the response to the responseInterceptor, and return the updated value from it.

//store the original fetch
const originalFetch = window.fetch;

// request interceptor
// perform all the pre-request actions
window.requestInterceptor = (args) => {
  // your action goes here
  return args;
}

// response interceptor
// perform all the post-response actions
window.responseInterceptor = (response) => {
  // your actions goes here
  return response;
}

// over-ride the original fetch
window.fetch = async (...args) => {  
    // request interceptor
    // pass the args to request interceptor
    args = requestInterceptor(args);
    
    // pass the updated args to fetch
    let response = await originalFetch(...args);
  
    // response interceptor
    // pass the response to response interceptor
    response = responseInterceptor(response);
    
    // return the updated response
    return response;
};

Test Case

As you can see in the requestInterceptor we are manually setting the page number and in the responseInterceptor we are returning the parsed JSON value.

Input:
// request interceptor
// perform all the pre-request actions
window.requestInterceptor = (args) => {
  // original request does not contains page info
  // assign the pagination in the interceptor
  args[0] = args[0] + "2";
  return args;
}

// response interceptor
// perform all the post-response actions
window.responseInterceptor = (response) => {
  // convert the value to json 
  // to avoid parsing every time
  return response.json();
}

fetch('https://jsonplaceholder.typicode.com/todos/')
  .then(json => console.log(json));

Output:
{
  "userId": 1,
  "id": 2,
  "title": "quis ut nam facilis et officia qui",
  "completed": false
}