I'm using Retrofit with OKHttp client for caching responses from a JSON API.
This works nicely.
However, if I take an action on the device which causes the data to update on the server I need a way to 'invalidate' a particular route in order to ensure that next time a request is made for this data, it is fetched from the server again rather than the now outdated cached version.
Currently, I've worked around this by explicitly calling the new route with a "no-cache" flag in the Cache-Control header of the request, but this forces me to download the new data before it is needed, potentially multiple times if multiple actions are taken, just to keep the cache up to date.
Is there a way I can mark a route / method in my retrofit/OKhttp client as cache expired, requiring a mandatory update over the network the next time it's requested?
You should use retrofit if you are trying to map your server API inside your application (type-safing). Retrofit is just an API adapter wrapped over okHTTP. If you want to type safe and modularise the interaction code with your API, use retrofit.
You cannot cache POST requests. Only GET requests can be cached. Inside the interceptors, you need to get chain. request() to get the current request and add Cache options to it.
For making HTTP requests Retrofit uses the OkHttp library. OkHttp is a pure HTTP/SPDY client responsible for any low-level network operations, caching, requests and responses manipulation.
To quote the official code sample using urls()
:
val urlIterator = cache.urls()
while (urlIterator.hasNext()) {
if (urlIterator.next().startsWith("https://www.google.com/")) {
urlIterator.remove()
}
}
With retrofit2 and OkHttp3 you can force a new response by adding a Cache-Control header to your API method definition parameters:
@GET("ws/something")
Something getSomething(@Header("Cache-Control") String cacheControl);
and then when calling you either supply null
for a (maybe-)cached version or "no-cache"
for a live version:
myApi.getSomething(forceRefresh ? "no-cache" : null);
This is now possible in OkHttp by using the Cache.urls()
function. As the documentation says:
The iterator supports Iterator.remove(). Removing a URL from the iterator evicts the corresponding response from the cache. Use this to evict selected responses.
This was merged into master late December 2014 and seems to be part of these tags (releases): parent-2.4.0-RC1 parent-2.4.0 parent-2.3.0 parent-2.2.0
There isn't an API for this, but there should be one. Please open an OkHttp issue to report this.
It'll probably take a while for us to implement because we'll need to figure out what the best API for this is. Invalidating a single URL is straightforward. Invalidating a range of URLs (say square.com/cash/*
) is more difficult because OkHttp's cache is currently organized by URL checksums. There's also ugly edge cases like what happens if the invalidated URL is currently being written to the cache.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With