Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Invalidation callback #304

Closed
nolde opened this issue Jul 25, 2022 · 10 comments · Fixed by #308
Closed

[Feature Request] Invalidation callback #304

nolde opened this issue Jul 25, 2022 · 10 comments · Fixed by #308
Labels
enhancement New feature or request

Comments

@nolde
Copy link

nolde commented Jul 25, 2022

Similar to axios-cache-adapter callback called invalidate.

With this callback, we could easily fine-tune the interceptor's behaviour, by inspecting the current request id, method and what not.

As an example, this is what I have right now, along with axios-cache-adapter:

async function invalidate (config, req) {
  if (req.forceRefresh) {
    await invalidateByForcedRefresh(config, req)
  } else if (req.method.toLowerCase() !== 'get') {
    await invalidateByMethod(config, req)
  }
}

It allows me to pass in extra arguments (like forceRefresh in this case) straight from each request, allows me to test for id patterns for clearing cache, etc.

The reason is that the current update[id] method can be a little too simplistic. I may have an user requesting GET /things?filter=alpha and GET /things?filter=beta, and I want both cached. When the user does POST /thing, I want to invalidate both entries with different filters. Currently, I would have to implement that into each request point, making sure I generate suitable IDs and clearing all caches after a success.

The callback would allow me to better defined default invalidation behaviour into a centralised place.

Edit:

Another common case is multiple page loading. GET /things and GET /things?nextPageToken=ABCDE are both parts of the same query, and both need to be invalidated if a new item is added.

@arthurfiorette
Copy link
Owner

If I changed the implementation to a one following this typescript definition, would everything be ok?

export type CacheProperties<R = unknown, D = unknown> = {
  ...
  
  update: Record<string, CacheUpdater<R, D>> | ((storage: AxiosStorage, response: CacheAxiosResponse<R, D>) => MaybePromise<void>);
}

Then you'll have to interact with the storage by yourself and invalidate/update any request that you want.

@nolde
Copy link
Author

nolde commented Jul 25, 2022

@arthurfiorette I believe that should work! As long as I have access to the current query id, and can set it on global config, it should be fine.

@arthurfiorette
Copy link
Owner

I would have to implement that into each request point

At some point you'll have to do this, either using a custom key generator to wrap all "similar" requests or doing an if/else inside cache.update to invalidate all "similir" requests.

@arthurfiorette
Copy link
Owner

and can set it on global config, it should be fine.

What do you mean by that?

@nolde
Copy link
Author

nolde commented Jul 25, 2022

@arthurfiorette

and can set it on global config, it should be fine.

What do you mean by that?

I mean that I need to be able to set it when calling setupCache, not when making the request.

I would have to implement that into each request point

At some point you'll have to do this, either using a custom key generator to wrap all "similar" requests or doing an if/else inside cache.update to invalidate all "similar" requests.

I would probably change the key generator (using generateKey) to have keys that contain a predefined prefix (defined in the requests). That way, when checking the updates, I would be able to remove all keys that contain a given prefix.

@arthurfiorette
Copy link
Owner

@nolde, are you up to create a PR?

@arthurfiorette
Copy link
Owner

@nolde, i got time and created a PR with the above changes. Can you take a look at it before I merge into prod?

arthurfiorette added a commit that referenced this issue Jul 29, 2022
* feat: implemented general cache updater function

* test: added tests

* docs: included cache update warning
@arthurfiorette
Copy link
Owner

@nolde, just released v0.10.7, can you test it out?

@ghost
Copy link

ghost commented Sep 7, 2022

Hi @arthurfiorette

I just started using axios-cache-interceptor today and so far so good!
Unfortunately I have the same problem as @nolde, I'm caching all the GET requests but some have parameters and need to get invalidated/updated after a POST to the same endpoint, here an example:

Request ID generation (url parameters included)
generateKey: buildKeyGenerator(({url, method}) => ${method?.toUpperCase()}/${url})
My axios' request's interceptor (I have a global axios instance using react's context api)
client.interceptors.request.use(
(config) => {
setBackdrop({...backdrop, open: true, type: config.method === "get" ? "loading" : "saving"});
return config;
},
(error) => {
setBackdrop({...backdrop, open: false});
return Promise.reject(error);
}
);

How can I invalidate/update cached GET requests in the interceptor? IDs are generated and not fixed like "list-posts" from your example.
Thanks in advance!

@arthurfiorette
Copy link
Owner

Moved to #344

@arthurfiorette arthurfiorette closed this as not planned Won't fix, can't repro, duplicate, stale Sep 8, 2022
@arthurfiorette arthurfiorette added the enhancement New feature or request label Nov 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants