Client Side Caching

Updated on 20-October-2016 at 10:16 AM

Business Catalyst End of life announcement - find out more details.

A content based caching system has been implemented in BC when using REST API endpoints.

In simple terms, if the content has not changed on the server, the server will respond with a HTTP status of 304 (Not Modified) and the data will be served from the browser instead.

What are ETags

According to RFC2616 , entity tags are used for comparing two or more entities from the same requested resource. HTTP/1.1 uses entity tags in the ETag, If-Match, If-None-Match and If-Range header fields.

The If-None-Match request-header field is used with a method to make it conditional. A client that has one or more entities previously obtained from the resource can verify that none of those entities is current by including a list of their associated entity tags in the If-None-Match header field.

The purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction overhead.

ETag Generation

The BusinessCatalysts' caching machanism will check the following when generating the ETag:

  • Headers
    • Host: apps uri
    • Accept: application/json
    • Content-Type: application/json
  • Query strings

GET

For every GET request, BC will return an ETag string in the Response Headers.

HTTP/1.1 200 OK
...
Content-Encoding:gzip
Content-Length:400
Content-Type:application/json; charset=utf-8
...
ETag: "rwsa6f9ub1f7geifth/nfq=="

 

Note: At this first request, the HTTP status is 200 and that content has been sent from the server.

On subsequent browser requests the If-None-Match request header is sent with the ETag value of the last requested version of the resource.

If-None-Match: "rwsa6f9ub1f7geifth/nfq=="

If the current version has the same ETag value, indicating its value is the same as the browser’s cached copy, then an HTTP status of 304 is returned.

HTTP/1.1 304 Not Modified
...
ETag: "rwsa6f9ub1f7geifth/nfq=="

 

Note: In this case, no data has been sent back by the server to the client, but the data is accesible as the browser has cached it.

POST, PUT, DELETE

Keep in mind, that any POST, PUT, DELETE on any resource will invalidate the cache and this will lead to a new generated ETag.

Example Requests

We will just do 3 recurring requests at page load using Javascript's XMLHttpRequest and the jQuery's AJAX request.

Let's first get a token in our app. Please follow this guide on how to build your first app.

var access_token = BCAPI.Helper.Site.getAccessToken();

We will get the same blogpost just for the sake of this exercise 3 times on page load:

Javascript

var jsVersion = (function(){
        var xhr = [];
        for (var i = 0; i < 3; i++){
            (function (i){
                xhr[i] = new XMLHttpRequest();
                url = "/webresources/api/v3/sites/current/blogposts/472900";
                xhr[i].open("GET", url, true);
                xhr[i].setRequestHeader("Authorization",$.cookie('access_token'));
                xhr[i].send();
            })(i);
        }
})();

jQuery

var jQueryVersion = (function(){
        var request = [];
        for (var i = 0; i < 3; i++){
            (function (i){
                request = $.ajax({
                    url: "/webresources/api/v3/sites/current/blogposts/472900",
                    type: "GET", 
                    contentType: "application/json",
                    cache: true,
                    ifModified: true,
                    headers: {
                        "Authorization": $.cookie('access_token')
                    }
                });
                request.done(function(data) {
                    console.log(data);
                });
                request.fail(function(jqXHR) {
                    console.log("Request failed.");
                    console.log("Error code: " + jqXHR.status);
                    console.log("Error text: " + jqXHR.statusText);
                    console.log("Response text: " + jqXHR.responseText);
                });
            })(i);
            
        }
})();

Just like described above, the HTTP status of the first call will be 200 OK while the subsequent 2 requests will have 304 Not Modified.

The ajax requests need to have the following additional settings for the ETag to function correctly:

  • cache: true (If set to false, it will force requested pages not to be cached by the browser)
  • ifModified: true (Allow the request to be successful only if the response has changed since the last request)