1. Introduction

This tutorial is going to cover about how to cache response with OkHttp, an HTTP & HTTP/2 client for Android and Java applications.

Fetching resource over the network is both slow and expensive. Therefore, OkHttp provides us ability to cache and reuse previously fetched resources similarly to many web browsers. Note that although OkHttpClient honors all HTTP/1.1 (RFC 7234) cache headers, it doesn’t cache partial responses.

2. How to Cache Response with OkHttp

To cache response with OkHttp, we’ll need:

  • A directory which can be read and write to, is used for cache storing.
  • The cache directory should be private, and untrusted applications should not be able to read its contents.
  • The same cache directory should not be used for multiple caches because accessing the same cache directory simultaneously causes error.
  • Most applications should call new OkHttpClient() exactly once, configure it with their cache, and use that same instance everywhere.

3. Cache Response with OkHttp Example

This section illustrates how we create an OkHttpClient and fetch resources from a remote HTTP request and response service which its responses will be cached in 20 seconds: http://httpbin.org/cache/20.

3.1. Preparation

We’re going to use OkHttp, version 3.5.0 for the example, and the only Maven dependency we will need is:

3.2. Example

Let’s see a part of a JUnit test class called CacheOkHttpExampleTest which will be used to illustrate some cache feature of OkHttp:

The initCache() method which is annotated with the @Before annotation, is used to initialize the OkHttpClient field and provide it a cache directory with 10MB size limit before any test method. The cache.evictAll() method is used to clear all the previous caches stored on the given directory to make sure all the tests will run correctly.

Here is an example of caching response with OkHttp:

First, we create a request to a remote HTTP service which will allow the response to be cached in 20 seconds, and then we execute the request:

Because this is the first request to the remote HTTP service, there was no response in cache. The client has to fetch resource directly from the server and then cache the response. As a result, the raw response which received from the network will be used and the response in cache is NULL.

Next, we use the same client  to execute another request to the remote HTTP service:

Because the response of the previous is in cache and is still fresh, the OkHttClient will use it instead of fetching from the remote server (The network response is NULL).

4. Cache Optimization

This section is going to cover some situations that we can optimize cache from the OkHttp client side.

4.1. Force a Network Response

In some situations, such as after a user clicks a ‘refresh’ button, it may be necessary to skip the cache, and fetch data directly from the server. To force a full refresh or force a network response, add the no-cache directive. Let’s see an example below:

At first, we create a request to the remote HTTP service and execute the request.

In similar to the first example, because the above request is the first request to server, there was no response in cache and the client will fetch resource directly from server and use it.

Note that response4, the response of this request, will be cached.

The next , we create a new request which doesn’t accept an unvalidated cached response, to the same remote HTTP service.

Then we use the same client created above to execute the request:

Even the previous response was in cache and is still fresh (reponse4), the client ignored it and did fetch the resource directly from the remote HTTP service.

4.2. Force a Cache Response

Sometimes, we’ll want to show resources if they are available immediately, but not otherwise. This can be used so our application can show something while waiting for the latest data to be downloaded. To restrict a request to locally-cached resources or force a cache response, add the only-if-cached directive. Let’s see an example below:

Firstly, we create a normal request to the remote HTTP service to fetch the resource and cache the response (response6)

Secondly, we create a new request which accepts only the response if it is in the cache, to the same remote HTTP service. We do this by adding the only-if-cached directive:

Then we execute the request:

Let’s verify the response:

This request will be execute successfully because the response in cache(reponse6) is still refresh and returned . Note that if the response isn’t available in the cache or requires server validation, the call will fail with a 504 Unsatisfiable Request.

Thirdly, we make the current thread sleep in 20 seconds to make sure the response in cache is stale. Then we execute the request again:

Because the response in cache was stale,  a 504 Unsatisfiable Request response was returned.

4.2.1. Permit Stale Cached Responses

In some situations, a stale response is better than no response. To permit stale cached responses, we can use the max-stale directive with the maximum staleness in seconds:

Firstly, we create a normal request to the remote HTTP service to fetch the resource and cache the response (response9)

Secondly, after making the current thread sleep in 20 seconds to make sure the cached response (response9) is stale, we create a new request to the same remote HTTP service but this request only accepts the response if it is in the cache.

Then we execute the request and a 504 Unsatisfiable Request response will be returned.

Lastly, we create another request and permit stale cached responses by setting the max-stale directive with the maximum staleness in 7 days:

Then we execute the request:

Different with the previous request which returned a 504 Unsatisfiable Request response, executing this request will return the stale response in cache.

5. Conclusion

The tutorial has shown us how to cache response with OkHttp and how to optimize those caches for our purposes such as to force a network response, to force a cache response, to permit stale cached responses . For effective using of cache, we firstly should understand about HTTP caching, the cache policies controlled from the server side and then apply and optimize the cache stored at the client side.

The example source code can be found the Github project or can be downloaded by clicking on the link java-okhttp-examples.zip. It is a Maven based project which will easily imported into IDEs such as Eclipse or Intellij.

6. References

HTTP Caching

OkHttp Cache Optimization

Java REST Client Examples Using OkHttp

Basic Authentication with OkHttp Example

Upload a File with OkHttp

Set Timeout with OkHttp

Download a File with OkHttp

WebSocket Client Example with OkHttp

 

 

0 0 vote
Article Rating