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.
What's inside 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.
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.Initialize axios-cache-interceptor with setupCache()
ThesetupCachefunction 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 */ });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);- Request Interceptors: Those registered before
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' } } }); }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 usingaxios.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();Set up axios-cache-interceptor for basic caching
To enable caching, use thesetupCachefunction 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 acachedboolean 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); // trueInstall axios-cache-interceptor
Installaxios-cache-interceptorandaxiosusing 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';Programmatically update cache after a mutation
When a client-side mutation occurs, you can programmatically update a specific cache entry using thecache.updateoption 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 uniqueidin 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; } } } } ); }Use Request IDs to control cache sharing
Theaxios-cache-interceptoruses a uniqueidfor each request to bind it to a specific cache entry. By manually providing anidin 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' });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 AxiostransformResponseoption 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 cachedAdd 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