axios-cache-interceptor icon indicating copy to clipboard operation
axios-cache-interceptor copied to clipboard

Possibility to opt-in cache

Open panghaoyuan opened this issue 2 years ago • 14 comments

I have an old project of nextjs project.. Most of the pages of the project do not need caching. I only need to use this cache on a few pages. How to set the global setting to disable caching, I only need to enable caching on a few pages. such as

axios.get('url', {
  cache: true,
});

or

axios.get('url', {
  cache: {
    open: true,
    ...otherOption
 },
});

how can i resolve this question

panghaoyuan avatar Feb 28 '23 09:02 panghaoyuan

Hey @panghaoyuan, disabling cache by default seems to be a no-op to this package ship as a feature.

If the hassle is worth, you can use cache: false on every page that cache should be disabled and use axios as normally on every page that cache should be enabled. Which is the currently recommended and default behavior of axios-cache-interceptor.

To incrementally adopt axios-cache-interceptor in your current system, I'd export two axios instances in your code, like axios and newAxios with cache enabled.

Feel free to reopen this issue :)

arthurfiorette avatar Mar 01 '23 01:03 arthurfiorette

I have an old project of nextjs project.. Most of the pages of the project do not need caching. I only need to use this cache on a few pages. How to set the global setting to disable caching, I only need to enable caching on a few pages. such as

axios.get('url', {
  cache: true,
});

or

axios.get('url', {
  cache: {
    open: true,
    ...otherOption
 },
});

how can i resolve this question

You could also try axios defaults perhaps.

import axios from "axios";

axios.defaults.cache = false;

CatchABus avatar Mar 01 '23 02:03 CatchABus

Just to leave a comment for anyone trying to achieve that and reaching here ... :

Adding axios.defaults.cache = false; alone won't work. By doing this you are "deleting" the cache object needed by this lib ....

That's what I've done to "activate" the cache to only 1 route :

setupCache(axiosInstance);

// After beign setup we store that cache settings
const savedCacheSettings = axiosInstance.defaults.cache;

// This will disable cache for all requests
axiosInstance.defaults.cache = false;

// then export this to whatever service you would like 
export const cacheSettings = savedCacheSettings;

And in whateverServiceYouWouldLike.js :

import axiosInstance, { cacheSettings } from 'AxiosSetup.js';

export const getXXXXX = async () => {
  axiosInstance.defaults.cache = cacheSettings;
  const r = await axiosInstance.get('/getSomething');
  
  // turns back cache to false for next calls
  axiosInstance.defaults.cache = false;
  return r;
};

And seems to be working ;)

seba9999 avatar Mar 01 '23 23:03 seba9999

An even simpler solution:

setupCache(axios, {
  // disable methods
  methods: [],
});

// For request with cache just add methods
const isCached = true;

const { data } = await axios.request({
  url: '/....',
  cache: {
          ...(isCached
            ? {
                methods: ['get'],
              }
            : {}),
        },
});

MatthewPattell avatar Oct 26 '23 10:10 MatthewPattell

According to the source code, I am currently using the following code to completely disable the default cache in my project

import axios from 'axios'
import { setupCache, defaultRequestInterceptor, AxiosCacheInstance } from 'axios-cache-interceptor'

const getCacheRequestInterceptor = (axios: AxiosCacheInstance) => {
  const defaultRequestInterceptorResult = defaultRequestInterceptor(axios)
  const onFulfilled = ((config, ...args) => {
    if (!config?.cache || (config?.cache as any)?.ttl <= 0) {
      config.cache = false
    }

    return defaultRequestInterceptorResult.onFulfilled(config, ...args)
  }) as typeof defaultRequestInterceptorResult.onFulfilled
  const apply = (() => axios.interceptors.request.use(onFulfilled)) as typeof defaultRequestInterceptorResult.apply

  return {
    ...defaultRequestInterceptorResult,
    onFulfilled,
    apply,
  }
}

const rawAxiosInstance = axios.create()

const axiosInstance = setupCache(rawAxiosInstance, {
  ttl: -1,
  requestInterceptor: getCacheRequestInterceptor(rawAxiosInstance as AxiosCacheInstance),
})

export default axiosInstance

CJY0208 avatar Aug 12 '24 02:08 CJY0208

@arthurfiorette

Can I add the default cache disable feature to this project?

This is very necessary for projects that want to manually use cache

Like this

import Axios from 'axios';
import { setupCache } from 'axios-cache-interceptor';

const instance = Axios.create(); 
const axios = setupCache(instance, {
  cache: false,
});

CJY0208 avatar Aug 12 '24 02:08 CJY0208

Just to leave a comment for anyone trying to achieve that and reaching here ... :

Adding axios.defaults.cache = false; alone won't work. By doing this you are "deleting" the cache object needed by this lib ....

That's what I've done to "activate" the cache to only 1 route :

setupCache(axiosInstance);

// After beign setup we store that cache settings
const savedCacheSettings = axiosInstance.defaults.cache;

// This will disable cache for all requests
axiosInstance.defaults.cache = false;

// then export this to whatever service you would like 
export const cacheSettings = savedCacheSettings;

And in whateverServiceYouWouldLike.js :

import axiosInstance, { cacheSettings } from 'AxiosSetup.js';

export const getXXXXX = async () => {
  axiosInstance.defaults.cache = cacheSettings;
  const r = await axiosInstance.get('/getSomething');
  
  // turns back cache to false for next calls
  axiosInstance.defaults.cache = false;
  return r;
};

And seems to be working ;)

This may cause issues in your application if you have multiple requests running simultaneously with different cache configurations.

sayhicoelho avatar Sep 20 '24 15:09 sayhicoelho

@arthurfiorette This is a needed feature since we don't want to have two axios instances in our applications. Disabling cache globally would be useful.

sayhicoelho avatar Sep 20 '24 15:09 sayhicoelho

What's the problem with 2 axios instances?

arthurfiorette avatar Sep 20 '24 16:09 arthurfiorette

@sayhicoelho You can try setting cache.override to true globally: https://axios-cache-interceptor.js.org/config/request-specifics#cache-override Cache will still be enabled but will get overridden every time by a new response.

Although, I think having another axios instance for them would be ideal.

CatchABus avatar Sep 20 '24 16:09 CatchABus

Cache will still be enabled but will get overridden every time by a new response.

Nice! I didn't think of that before. This is probably the best solution since once override: false, you already have a lot of populated data.

arthurfiorette avatar Sep 20 '24 16:09 arthurfiorette

@arthurfiorette

Can I add the default cache disable feature to this project?

This is very necessary for projects that want to manually use cache

Like this

import Axios from 'axios';
import { setupCache } from 'axios-cache-interceptor';

const instance = Axios.create(); 
const axios = setupCache(instance, {
  cache: false,
});

@arthurfiorette I need exectly the same feature: disabled cache by default but with options specified.

mahnunchik avatar Oct 18 '24 12:10 mahnunchik

It seems that a lot of people are wanting this feature, I'll reopen this issue in case someone wants to work on it.

remember to add unit tests :)

arthurfiorette avatar Oct 18 '24 12:10 arthurfiorette

I think adding multiple instances of axios with distinct caching settings might be a possible workaround here. I don’t encounter any errors from running setupCache multiple times as long as I pass a different axios instance each time and this allows caching to be enabled only where needed, by using the cached instance.

Additionally, extracting other global logic into a function that accepts an axios instance simplifies applying other interceptors consistently across all instances.

Pseudo-code:

import { setupCache } from 'axios-cache-interceptor'

// Function to add authentication interceptors
function addAuthToAxiosInstance(instance) {
  instance.interceptors.request.use(config => { /* add token */ });
  instance.interceptors.response.use(response => response, error => { /* handle auth errors */ });
}

// Create axios instances with different caching settings
const globalAxios = axios.create({})
const inMemoryCachedAxios = setupCache(axios.create(), { /* in-memory cache config */ })
const persistentCachedAxios = setupCache(axios.create(), { /* persistent cache config */ })

// Apply auth logic to each instance
addAuthToAxiosInstance(globalAxios)
addAuthToAxiosInstance(inMemoryCachedAxios)
addAuthToAxiosInstance(persistentCachedAxios)

export { globalAxios, inMemoryCachedAxios, persistentCachedAxios }

This setup allows selective caching with minimal code changes and keeps the configuration for each API call flexible.

M-Matin-dev avatar Oct 29 '24 16:10 M-Matin-dev