Duplicate API requests are common and if dealt wisely, can help developers in creating a seamless user experience. In a scalable application, duplicate API requests can be problematic to the resources on a server, can affect the cost, and can interrupt performance.
That is why it is important to pay attention to API calls and ensure that no duplicate request is passed to the API. The later segment discusses some of the probable reasons that can lead to duplicate API request issues and ways to overcome the problem.
Duplicate API Requests: Possible Reasons
There can be different scenarios where an API is called multiple times to get the data. For example,
- When a user taps on a button multiple times before it gets disabled.
- At times, one API response causes another API request to execute. Let’s understand this with an analogy. There are several books with the same author details. As the details of the book get loaded, another requests to load the author's details is passed consequently. In this scenario, the request for multiple book details can hit the author's details API (while one is already under execution).
- API requests on scroll events can hit an API multiple times as the scroll event triggers rapidly.
Same API called multiple times
Fixing Duplicate API Request Problem
While there can be several ways to fix this problem, the one that we share here leverages promise behaviour, which requires minimal changes to the codebase. Let’s understand how this solution works.
‘Promise’ is an effective tool to handle asynchronous processes. Here is an implementation of promises to handle duplicate API requests.
class MemoPromise {
constructor(getPromise) {
this.cache = {};
this.getPromise = getPromise;
this.request = this.request.bind(this);
}
request({ uniqueKey, ...rest }) {
if (!uniqueKey) {
return Promise.reject(new Error('Unique key not passed'));
}
if (this.cache[uniqueKey]) {
return this.cache[uniqueKey];
}
const promise = this.getPromise(rest);
this.cache[uniqueKey] = promise
.then((res) => {
delete this.cache[uniqueKey];
return res;
})
.catch((err) => {
delete this.cache[uniqueKey];
throw err;
});
return this.cache[uniqueKey];
}
}
In the above example, we have created a MemoPromise class whose instantiated object can memorize the promises returned by the passed function in the constructor till the time they are not resolved or rejected. The aforementioned implementation can be executed as below:
const memoPromise = new MemoPromise(fn);
// invocation
const { request } = memoPromise;
request({ uniqueKey: url, apiType, url, payload });
// not required now
// fn({ apiType, url, payload });
`fn` is the method under which API request is defined and it returns the request made as a promise (which is default). Instead of calling `fn` each time now we will be calling the `request` method consisted of memoPromiseObj.
No Duplicate API Requests
By integrating the MemoPromise class, it is possible to effectively deal with duplicate API requests. We hope this works with you as well.
For any query or discussion, you can initiate a conversation through the comments section below.