Axios Cache Interceptor

website·Indexed 30 days ago

https://axios-cache-interceptor.js.org/

An interceptor for Axios that provides caching capabilities for HTTP requests. It includes features for cache invalidation, storage adapters for saving and retrieving cache entries (such as IndexedDB), request ID generation, and a setupCache() function for configuration.

Tokens
7.1K
Snippets
41
Records
51
Agent score
63%

What's inside Axios Cache Interceptor

  1. Overview of Axios Cache Interceptor

    Axios Cache Interceptor is a caching layer for Axios that prevents network overloading by intercepting requests and returning cached responses when available. Unlike adapters, it uses axios interceptors to remain minimally invasive, allowing developers to continue using any axios adapter of their choice. The interceptor checks for cached valid responses or pending network requests before allowing a request to reach the adapter, and saves cacheable responses to storage after they are received.
  2. Understand the Axios Cache Interceptor Response object

    Axios Cache Interceptor extends the standard axios response object to include metadata about the cache state and request identification. This allows developers to determine if a response was served from the cache and whether that cached data was fresh or stale.
  3. Initialize axios-cache-interceptor with setupCache()

    The setupCache function initializes the cache interceptor by modifying an axios instance in place and returning it. It can be used with a custom axios instance or the default global axios instance to apply caching to all requests.
    import Axios from 'axios';
    import { setupCache } from 'axios-cache-interceptor';
    
    // For a specific instance
    const axiosInstance = Axios.create();
    const axios = setupCache(axiosInstance, { /* options */ });
    
    // For the global axios instance
    setupCache(Axios, { /* options */ });
  4. Manage execution order of axios-cache-interceptor and other interceptors

    Axios executes request interceptors in reverse order (LIFO) and response interceptors in normal order (FIFO). When using setupCache(axios), the cache interceptors are attached immediately.

    • Request Interceptors: Those registered before setupCache() run after the cache; those registered after run before the cache.
    • Response Interceptors: Those registered before setupCache() run before the cache; those registered after run after the cache.
    // This will run AFTER the cache interceptor
    axios.interceptors.request.use((req) => req);
    
    // This will run BEFORE the cache interceptor
    axios.interceptors.response.use((res) => res);
    
    setupCache(axios);
    
    // This will run BEFORE the cache interceptor
    axios.interceptors.request.use((req) => req);
    
    // This will run AFTER the cache interceptor
    axios.interceptors.response.use((res) => res);
  5. Invalidate cache via network revalidation

    If a mutation is too complex to replicate programmatically on the client, you can invalidate the cache entry. Setting the update value to 'delete' for a specific request ID will remove that entry from storage, forcing the next request for that resource to be forwarded to the server.
    function listPosts() {
      return axios.get('/posts', {
        id: 'list-posts'
      });
    }
    
    function createPost(data) {
      return axios.post('/posts', data, {
        cache: {
          update: {
            // Removes 'list-posts' from storage; next call to listPosts() will fetch from server
            'list-posts': 'delete'
          }
        }
      });
    }
  6. Manually manage cache storage from external sources

    For updates triggered by external events (e.g., WebSocket messages), you can interact with the cache storage directly using axios.storage. This allows you to remove specific entries or clear the entire cache outside of a request context.
    // Delete a specific cache entry by its ID
    await axios.storage.remove('list-posts');
    
    // Clear all cached data
    await axios.storage.clear();
  7. Set up axios-cache-interceptor for basic caching

    To enable caching, use the setupCache function to wrap an Axios instance. This attaches the necessary cache interceptors to the instance. Subsequent requests to the same URL will be served from the cache, and the response object will include a cached boolean property indicating if the response was retrieved from the cache.
    import Axios from 'axios';
    import { setupCache } from 'axios-cache-interceptor';
    
    const instance = Axios.create();
    const axios = setupCache(instance);
    
    const req1 = axios.get('https://api.example.com/');
    const req2 = axios.get('https://api.example.com/');
    
    const [res1, res2] = await Promise.all([req1, req2]);
    
    console.log(res1.cached); // false
    console.log(res2.cached); // true
  8. Install axios-cache-interceptor

    Install axios-cache-interceptor and axios using a package manager or via CDN for browser environments.
    npm install axios@^1 axios-cache-interceptor@^1

    <!-- Browser UMD builds --> <!-- Development (ES2017+) --> <script src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@1/dev/index.bundle.js"></script> <!-- Production (ES5+) --> <script src="https://cdn.jsdelivr.net/npm/axios-cache-interceptor@1/dist/index.bundle.js"></script>

    <!-- Skypack -->

    import Axios from 'https://cdn.skypack.dev/axios';
    import { setupCache } from 'https://cdn.skypack.dev/axios-cache-interceptor';
  9. Programmatically update cache after a mutation

    When a client-side mutation occurs, you can programmatically update a specific cache entry using the cache.update option in the request config. This allows you to modify the cached data without making another network request. To reference a specific request's cache, you must provide a unique id in the original request.
    // 1. Define a request with a unique ID
    function listPosts() {
      return axios.get('/posts', {
        id: 'list-posts'
      });
    }
    
    // 2. Update that specific cache entry after a mutation
    function createPost(data) {
      return axios.post(
        '/posts',
        data,
        {
          cache: {
            update: {
              'list-posts': (listPostsCache, createPostResponse) => {
                // Only update if the entry is actually cached
                if (listPostsCache.state !== 'cached') {
                  return 'ignore';
                }
    
                // Update the cached data (e.g., push new post to the list)
                listPostsCache.data.posts.push(createPostResponse.data);
    
                return listPostsCache;
              }
            }
          }
        }
      );
    }
  10. Use Request IDs to control cache sharing

    The axios-cache-interceptor uses a unique id for each request to bind it to a specific cache entry. By manually providing an id in the request configuration, you can force different requests to share the same cache or force the same endpoint to use different caches based on the context.
    import Axios from 'axios';
    import { setupCache } from 'axios-cache-interceptor';
    
    const axios = setupCache(Axios);
    
    // Force two different endpoints to share the same cache
    await axios.get('/a', { id: 'custom-id' });
    await axios.get('/b', { id: 'custom-id' });
    
    // Force the same endpoint to use different caches for different contexts
    await axios.get('/users', { id: 'users-page-x' });
    await axios.get('/users', { id: 'users-page-y' });
  11. Cache non-JSON responses or streams

    The cache interceptor only handles serializable data types. To cache a stream or non-JSON response, use the native Axios transformResponse option to convert the data into a string or buffer before it reaches the cache interceptor.
    import Axios from 'axios';
    import { setupCache } from 'axios-cache-interceptor';
    
    const instance = Axios.create();
    const axios = setupCache(instance);
    
    const response = await axios.get('my-url-that-returns-a-stream', {
      responseType: 'stream',
      transformResponse(response) {
        // Convert stream to string or object to make it serializable
        return convertStreamToStringOrObject(response.data);
      }
    });
    
    response.data; // Now a string and can be cached
  12. Add axios-cache-interceptor skills to AI coding assistants

    If using an AI coding assistant that supports the Skills framework, you can install the library's skill to provide the assistant with up-to-date API references and usage patterns.
    npx skills add arthurfiorette/axios-cache-interceptor