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

Unable to cache post requests with paramerters

Open gautamkrishnar opened this issue 5 years ago • 15 comments

I have a POST API That returns values on submission of some values as POST params, i was not able to implement caching to this API even if i had used the custom invalidate function. Please find the code below:

import localforage from "localforage";
import { setup } from 'axios-cache-adapter';

const localStorageStore = localforage.createInstance({
    driver: [localforage.INDEXEDDB, localforage.LOCALSTORAGE],
    name: "api-cache"
});

let configObj = {};
configObj.cache = {
            maxAge: 24 * 60 * 60 * 1000,
            store: localStorageStore,
            debug: true,
            exclude: {
                query: false
            },
            invalidate: async (config, request) => {
                if (request.clearCacheFlag) {
                    await config.store.removeItem(config.uuid);
                }
            }
        };
const api = setup(configObj);

GET Requests is working fine...

gautamkrishnar avatar May 21 '19 19:05 gautamkrishnar

Hi @gautamkrishnar for now it impossible to cache POST requests, they are blocked directly in the code, sorry.

It will come in the v3 but I have no ETA to give yet.

Cheers :beers:

ghost avatar May 21 '19 20:05 ghost

It should be mentioned in the docs. I've just wasted two hours figuring this out and tweaking invalidate function. Can you point out where it's handled in the code? I'll make a fork for myself. I'm using mainly POST for Elasticsearch queries, it's crucial to have POST requests cached.

pawelotto avatar Jul 18 '19 07:07 pawelotto

@pawelotto POST requests are not intended to be cached, since their primary purpose is to create resources. Same with PUT, PATCH, DELETE, etc. ElasticSearch uses this method to avoid complex query strings (like Solr does).

Even if v3 will allow caching POST requests, there's no caching implementation that I know which will take the request body into account for generating the unique cache key. @RasCarlito is that your plan?

bpolaszek avatar Jul 18 '19 08:07 bpolaszek

@bpolaszek Nevermind, I've already created a fork that supports all methods and Elasticsearch works great with POST caching enabled. Since I'm only using it to cache Elasticsearch queries I don't recommend it for anything else because I didn't test it.

pawelotto avatar Jul 18 '19 08:07 pawelotto

No plan to serialize request body into cache key for now, but it seems quite absurd to not implement it 😄

@pawelotto Yes the fact that none GET requests were not cached should have been mentioned in docs more clearly, sorry about that.

ghost avatar Jul 18 '19 09:07 ghost

Just so I'm clear, are you saying that the body is not taken into account for all methods, or just POST, PUT, PATCH, DELETE? :O

AndrewCraswell avatar Jul 29 '19 01:07 AndrewCraswell

Hey @AndrewCraswell

As @bpolaszek said, the request body is not taken into account for any method to generate the unique cache key.

Now that I think of it I don't think it's a great idea, serializing the body of the request could generate too long keys. Maybe just using the request method as part of the cache key to have different cache for a same URL called with different HTTP methods would do the trick. But we'd also need to have some mechanism to easily discard cache IMO.

Else if you're asking if the HTTP response body is taken into account, yes it is. But for now it is impossible to cache other than GET requests.

Check the v3 beta if you'd like to cache other than GET requests.

ghost avatar Aug 08 '19 19:08 ghost

If I'm understanding right, this seems like a critical missing piece. Having used other cache systems over the years, I think this is necessary. Consider the following valid requests:

GET /api/users { ids: [10, 13, 2, 8] } GET /api/users { ids: [54, 89] }

In this case, the second request for user's 54 and 89 would return the cached results of the previous call. At a minmum, I think the url, method, and body should generally be hashed to create the cache key.

AndrewCraswell avatar Aug 13 '19 07:08 AndrewCraswell

Ok I get your point 😄

Just one thing bothered me, even though GET requests with a body are valid HTTP they are not recommended at all as is better explained here.

For other request methods I understand that it should be done and could be applied to GET requests as well even though it should not be used 😄

Will look into it @AndrewCraswell

ghost avatar Aug 13 '19 09:08 ghost

Hi there, just been playing around with @pawelotto fork of this. Currently the POST Request is being cached and is visible in the Api Memory Store. However, the consecutive POST requests still continue to make the request whilst not retrieving the data from the cache.

Is there a reason why this is? It works fine for the GET requests.

JohnChangUK avatar Sep 26 '19 16:09 JohnChangUK

@RasCarlito Hello Ras, I can make this available in v2 until you release v3. I'm thinking of hashing the request body and concat it to URL and serialized query params.

mohamedgomran avatar Oct 20 '19 11:10 mohamedgomran

@RasCarlito I implemented it, I can open a PR.

mohamedgomran avatar Oct 20 '19 16:10 mohamedgomran

@mohamedgomran At first I did not want to release this in thee v2 version range as this seemed to be a breaking change. But as long as the default behavior stays the same I have no issue with being able to cache post requests using v2.

If you have a PR I'll gladly merge/release it

ghost avatar Nov 12 '19 15:11 ghost

Any movement on this one? I'm noticing that the adapter won't cache the following http://solr-server.co.com:8983/solr/people/select?q=firstname:Fred*&rows=200&start=0&wt=json&json.nl=arrarr

Is it because of the query params?

occasl avatar Apr 02 '20 22:04 occasl

Any news for this feature ?

@mohamedgomran did it on his repo ... But linked to this problem with npm7 I can't use it in my CI ...

@RasCarlito Is this implemented in the V3 ? Could you elaborate on this sentence ? : " Cache non GET requests with a custom exclusion config "

I can't tell if it takes into account the POST params ... with an hash as mohamedgomran did ?

seba9999 avatar Nov 22 '21 19:11 seba9999