⚡ feat: implement GET request deduplication in API layer
Add request deduplication mechanism to prevent duplicate GET requests to the same endpoint within the same timeframe, significantly reducing unnecessary network overhead. **Changes:** - Add `patchAPIInstance()` function to intercept and deduplicate GET requests - Implement in-flight request tracking using Map with URL+params as unique keys - Apply deduplication patch to both initial API instance and `updateAPI()` recreated instances - Add `disableDuplicate: true` config option to bypass deduplication when needed **Benefits:** - Eliminates redundant API calls caused by component re-renders or rapid user interactions - Reduces server load and improves application performance - Provides automatic protection against accidental duplicate requests - Maintains backward compatibility with existing code **Technical Details:** - Uses Promise sharing for identical concurrent requests - Automatically cleans up completed requests from tracking map - Preserves original axios functionality with minimal overhead - Zero breaking changes to existing API usage Addresses the issue observed in EditChannel.js where multiple calls were made to the same endpoints during component lifecycle.
This commit is contained in:
@@ -12,6 +12,36 @@ export let API = axios.create({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function patchAPIInstance(instance) {
|
||||||
|
const originalGet = instance.get.bind(instance);
|
||||||
|
const inFlightGetRequests = new Map();
|
||||||
|
|
||||||
|
const genKey = (url, config = {}) => {
|
||||||
|
const params = config.params ? JSON.stringify(config.params) : '{}';
|
||||||
|
return `${url}?${params}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
instance.get = (url, config = {}) => {
|
||||||
|
if (config?.disableDuplicate) {
|
||||||
|
return originalGet(url, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = genKey(url, config);
|
||||||
|
if (inFlightGetRequests.has(key)) {
|
||||||
|
return inFlightGetRequests.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
const reqPromise = originalGet(url, config).finally(() => {
|
||||||
|
inFlightGetRequests.delete(key);
|
||||||
|
});
|
||||||
|
|
||||||
|
inFlightGetRequests.set(key, reqPromise);
|
||||||
|
return reqPromise;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
patchAPIInstance(API);
|
||||||
|
|
||||||
export function updateAPI() {
|
export function updateAPI() {
|
||||||
API = axios.create({
|
API = axios.create({
|
||||||
baseURL: import.meta.env.VITE_REACT_APP_SERVER_URL
|
baseURL: import.meta.env.VITE_REACT_APP_SERVER_URL
|
||||||
@@ -22,6 +52,8 @@ export function updateAPI() {
|
|||||||
'Cache-Control': 'no-store',
|
'Cache-Control': 'no-store',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
patchAPIInstance(API);
|
||||||
}
|
}
|
||||||
|
|
||||||
API.interceptors.response.use(
|
API.interceptors.response.use(
|
||||||
|
|||||||
Reference in New Issue
Block a user