Created
          September 29, 2025 05:36 
        
      - 
      
 - 
        
Save opentechnologist/f4d3d2443eeaeb16616e76621e4036d3 to your computer and use it in GitHub Desktop.  
    a simple axios request interceptor implementation to cache response data for a particular period of time to optimize multiple endpoint requests.
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | class ApiCache { | |
| static CACHE_KEY_PREFIX = '__API_CACHE__'; | |
| constructor(axios) { | |
| this.axios = axios.create(); | |
| this.axios.interceptors.request.use(this.requestInterceptor.bind(this)); | |
| } | |
| // djb2 hash function | |
| hash(str) { | |
| let hash = 5381; | |
| for (let i = 0; i < str.length; i++) { | |
| hash = (hash << 5) + hash + str.charCodeAt(i); | |
| } | |
| return (hash >>> 0).toString(36); | |
| } | |
| buildCacheKey(url, params) { | |
| const str = params | |
| ? Object.keys(params) | |
| .sort() | |
| .map((k) => `${k}=${encodeURIComponent(params[k])}`) | |
| .join('&') | |
| : ''; | |
| const hash = this.hash(`${url}?${str}`); | |
| return `${ApiCache.CACHE_KEY_PREFIX}${hash}`; | |
| } | |
| requestInterceptor(config) { | |
| const { url, params, cacheDuration } = config; | |
| if (!cacheDuration) return config; | |
| const cacheKey = this.buildCacheKey(url, params); | |
| const cached = localStorage.getItem(cacheKey); | |
| if (cached) { | |
| let expired = true; | |
| try { | |
| const { expiration, data } = JSON.parse(cached); | |
| const now = Date.now(); | |
| if (now < expiration) { | |
| console.log(`CACHE HIT [${expiration - now}]`); | |
| expired = false; | |
| return Promise.reject({ | |
| __cachedData: true, | |
| config, | |
| data, | |
| status: 200, | |
| statusText: 'OK (CACHED)', | |
| headers: {}, | |
| }); | |
| } | |
| // } catch (e) { | |
| } finally { | |
| if (expired) { | |
| console.log(`CACHE EXPIRED [${expiration - now}]`); | |
| localStorage.removeItem(cacheKey); | |
| } | |
| } | |
| } else { | |
| console.log('CACHE MISS'); | |
| } | |
| return config; | |
| } | |
| get(url, params = {}, config = {}) { | |
| const cacheDuration = config.cacheDuration; | |
| const millisecond = cacheDuration ? cacheDuration * 60 * 1000 : 0; | |
| const expiration = cacheDuration ? Date.now() + millisecond : undefined; | |
| const cacheKey = this.buildCacheKey(url, params); | |
| const axiosConfig = Object.assign({}, config, { params, cacheDuration }); | |
| return this.axios | |
| .get(url, axiosConfig) | |
| .then((response) => { | |
| const data = response.data; | |
| if (cacheDuration) { | |
| localStorage.setItem( | |
| cacheKey, | |
| JSON.stringify({ | |
| expiration, | |
| data, | |
| url, | |
| params, | |
| }), | |
| ); | |
| } | |
| return response.data; | |
| }) | |
| .catch((error) => { | |
| if (error.__cachedData) { | |
| return error.data; | |
| } | |
| throw error; | |
| }); | |
| } | |
| remove(url, params = {}) { | |
| const cacheKey = this.buildCacheKey(url, params); | |
| localStorage.removeItem(cacheKey); | |
| } | |
| clearExpired() { | |
| Object.keys(localStorage).forEach((key) => { | |
| if (key.startsWith(ApiCache.CACHE_KEY_PREFIX)) { | |
| const { expiration } = JSON.parse(cached); | |
| const now = Date.now(); | |
| if (expiration < now) { | |
| localStorage.removeItem(key); | |
| } | |
| } | |
| }); | |
| } | |
| clearAll() { | |
| Object.keys(localStorage).forEach((key) => { | |
| if (key.startsWith(ApiCache.CACHE_KEY_PREFIX)) { | |
| localStorage.removeItem(key); | |
| } | |
| }); | |
| } | |
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | const api = new ApiCache(axios); | |
| api | |
| .get( | |
| 'https://jsonplaceholder.typicode.com/photos', | |
| {}, | |
| { | |
| cacheDuration: 5, // in minutes | |
| }, | |
| ) | |
| .then((response) => console.log(response)); | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment