Http Caching for Web API Responses

A Web API serves a client e.g. browser with an HTTP response upon receiving an HTTP request. Sometimes these responses could be huge size wise and this can lead to delays in displaying the response to the user. To cater such things, almost all the web browsers (Chrome, IE, Mozilla) have built-in capabilities to cache the http responses for a given timespan. A cache is an in memory store for data which is used to improve the performance. Read more about cache…

Caching of a response at the browser is not automatic. In the response headers we have to raise max-age or expires flag to tell the browser, it has to cache the response for a given timespan. Until this cache remains valid, browser picks data from cached response rather going back to the server again.

Validity of browser’s cache depends on the value of max-age or expires headers. You can read more about Http headers here Or specifically look for Cache-Control here.

In Web API we can take advantage of action filter attributes to set these headers values. Let see the following example, CacheHeaderFilterAttribute is used for PersonController to enable http cache

  [CacheHeaderFilterAttribute]
  public class PersonController : ApiController
  {
    public HttpResponseMessage Get()
    {
      // Create response, here it's empty for demostration 
      return Request.CreateResponse(HttpStatusCode.OK);
    }

  }

 

  class CacheHeaderFilterAttribute : ActionFilterAttribute
  {    
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {      
      TimeSpan expiration = TimeSpan.FromDays(24);

      // Either set the actionExecutedContext.Response.Content.Headers.Expires 
      if (actionExecutedContext.Response.Content != null)
      {
        actionExecutedContext.Response.Content.Headers.Expires = new DateTimeOffset(SystemTime.Now.Add(expiration));
      }

      // Or set the actionExecutedContext.Response.Headers.CacheControl.MaxAge
      actionExecutedContext.Response.Headers.CacheControl = new CacheControlHeaderValue() { MaxAge = expiration, Public = true };           
    }

  }

Note: You don’t need to specify both Expires and MaxAge

Choosing Between Expires and MaxAge : Expires is an absolute value which tells the date and time when cache will be invalidated. While MaxAge is a TimeSpan value which is added to the date and time value when response was received by the browser to check if cache is still valid. e.g. MaxAge is set to 24 hours in the above example. Suppose browser receives this request on 24 Dec 11:00 AM, this cache will remain valid until 25 Dec 11:00 AM.

If a response contains one of these headers, it uses that header But if a response contains both expires and max-age, max-age will take precedence over expires and will be used by browser to infer the validity of cache.

An finally where to see for cached responses. In chrome visit chrome://cache/ and we will get a list of cached responses. If we click to see the details of a single response, it would show the cache expiration date/time like. max-age is stored in seconds.

HTTP/1.1 200 OK
Cache-Control: public, max-age=900
Content-Type: application/json; charset=utf-8
Content-Language: en
Expires: Tue, 01 Nov 2016 06:12:29 GMT
Vary: Accept-Language
Server: Microsoft-IIS/8.5
X-Frame-Options: SAMEORIGIN
Date: Tue, 01 Nov 2016 05:57:28 GMT

Leave a Reply