🗄️🔥💨
Axios Cache Interceptor
axios-cache-interceptor
is a axios wrapper for caching and preventing unneeded requests
import axios from 'axios';
import { useCache, SessionCacheStorage } from 'axios-cache-interceptor';
const api = useCache(axios.create(), {
});
const resp1 = await api.get('https://api.example.com/');
const resp2 = await api.get('https://api.example.com/');
Table of contents
Installing
Axios is a peer dependency and must be installed separately.
npm install --save axios axios-cache-interceptor
yarn add axios axios-cache-interceptor
Support list
Below you can check what version of this package is supported by your version of axios.
But that does not mean that won't work with any version. Most of "breaking changes" made
by axios was it's types.
NOTE: Below v0.3, axios was not configured as a peer dependency
Version | Axios |
---|
~v0.5 | >= v0.24 |
~v0.4 | >= v0.23 |
~v0.3 | >= v0.22 |
<= v0.2 | v0.21 |
Getting Started
To you use this cache interceptor, you can apply to an existing instance or create a new
one.
import { useCache } from 'axios-cache-interceptor';
let axios;
axios = useCache(axios, {
});
or by creating a new one:
import { createCache } from 'axios-cache-interceptor';
const axios = createCache({
});
After that, you can made your own requests normally.
Support list
Compiled code
Currently, the typescript compiler is only used to remove types from code, emitting almost
the same output code as if this library were written in javascript. Nowadays, it is
practically mandatory to use some pre-processor, like Babel. So for the support of
multiple users in the browser, we recommend you to use it as well.
Current target: ES2020
Build options: tsconfig.json
Basic Knowledge
Request id
A good thing to know is that every request passed through this interceptor, has an id.
This does not mean that is a unique id. The id is used in a number of ways, but the
most important is to bind a request to its cache.
The id generation is good enough to generate the same id for theoretically sames requests.
The example of this is a request with { baseUrl: 'https://a.com/', url: '/b' }
results
to the same id with { url: 'https://a.com/b/' }
.
Also, a custom id can be used to treat two requests as the same.
axios.get('...', {
id: 'my-custom-id',
cache: {
}
});
The default id generation can clarify this idea.
Response object
Every response that came from our custom axios instance, will have some extras properties,
that you can retrieve like that:
const result = await cache.get();
const id = result['propertyName'];
response.cached
A simple boolean to check whether this request was cached or not.
NOTE: The first response of a request capable of being cached will return
cached: false
, as only your next requests will return cached: true
.
response.id
The request id resolved. This property represents the ID used throughout
the internal code. Remember that, depending on the
config.keyGenerator, it can be different as the provided on the
request.id.
Global configuration
When applying the interceptor, you can customize some properties:
const axios = createCache({
});
config.storage
The storage used to save the cache. Here will probably be the most changed property.
Defaults to MemoryStorage.
You can create your own implementation by implementing
CacheStorage.
There are few built in storage implementations, you can use them by importing:
import 'axios-cache-interceptor/dist/storage/{name}';
config.generateKey
The function used to create different keys for each request. Defaults to a function that
priorizes the id, and if not specified, a string is generated using the method, baseUrl,
params, and url.
config.waiting
A simple object that will hold a promise for each pending request. Used to handle
concurrent requests.
Can also be used as type of listener to know when a request is finished.
The function used to interpret all headers from a request and determine a time to live
(ttl
) number.
Check out the inline documentation to know how to modify your own.
config.requestInterceptor and config.responseInterceptor
The used request and response interceptor. Basically the core function of this library.
Check out the used request and
response to see the default used.
Per-request configuration
By using this axios client and using an ide with intellisense, you'll see a custom
property called cache
.
The inline documentation is self explanatory, but here are some examples and information:
request.id
You can override the request id used by this property.
request.cache.ttl
The time that the request will remain in cache. Some custom storage implementations may
not respect 100% the time.
When using interpretHeader
, this value is ignored.
If activated, when the response is received, the ttl
property will be inferred from the
requests headers. See the actual implementation of the
interpretHeader
method for more information. You can
override the default behavior by setting the headerInterpreter
when creating the cached
axios client.
request.cache.methods
Specify what request methods should be cached.
Defaults to only GET
methods.
request.cache.cachePredicate
An object or function that will be tested against the response to test if it can be
cached. See the inline documentation for more.
An simple example with all values:
axios.get('url', {
cache: {
cachePredicate: {
statusCheck: [200, 399],
containsHeader: {
'x-custom-header': true,
'x-custom-header-2': 'only if matches this string',
'x-custom-header-3': (value) => true
},
responseMatch: (response) => {
return response.auth.status === 'authenticated':
}
}
}
});
request.cache.update
Once the request is resolved, this specifies what other responses should change their
cache. Can be used to update the request or delete other caches. It is a simple Record
with the request id.
Example:
let otherResponseId;
let userInfoResponseId;
axios.get('url', {
cache: {
update: {
[otherResponseId]: 'delete',
[userInfoResponseId]: (cachedValue, thisResponse) => {
return { ...cachedValue, user: thisResponse.user.info };
}
}
}
});
request.cache.etag
If the request should handle ETag
and If-None-Match support
. Use a string to force a
custom static value or true to use the previous response ETag. To use true
(automatic
etag handling), interpretHeader
option must be set to true
. Default: false
request.cache.modifiedSince
Use If-Modified-Since
header in this request. Use a date to force a custom static value
or true to use the last cached timestamp. If never cached before, the header is not set.
If interpretHeader
is set and a Last-Modified
header is sent then value from that
header is used, otherwise cache creation timestamp will be sent in If-Modified-Since
.
Default: true
License
Licensed under the MIT. See LICENSE
for more informations.
Contact
See my contact information on my github profile or
open a new issue.