Selectively Caching a HttpResponseMessage with Polly - caching series 1/3

Full source code here.

Want to learn more about Polly? Check out my Pluralsight course on it.

When I give talks on Polly I show how to use it in a Web API application that calls another Web Api application. I give a simple example of how to use the cache policy where I store the whole of the HttpResponseMessage. At the end of the talk I often get a couple of questions -

1. is it possible to cache the response only when the status code is in the 200 range. 2. is it possible to cache the values inside the response instead of the whole response.

The answer to both of these is yes, and in this series of three articles I will explain how to do both of these things, and how how to combine them to cache a value inside a response only if the response is in the 200 range.

This article will demonstrate how to selectively cache HttpResponseMessages based on the Http StatusCode of the response. The second will show how to cache values inside the HttpResponseMessage, and the third will show how selectively cache values inside the HttpResponseMessage.

As described in an earlier post, using a cache policy is a little more involved than using other policies. See this post for more info.

Changes in Startup

In Startup inside ConfigureServices I setup the memory cache, the HttpClientFactory and a policy registry (I’m not going to go into a detailed explanation of this code as it is already explained in the earlier article and you have all the source code).

All the action for this post takes place in the Configure method.

Creating the cache filter

The cache timeout filter, it sets the length of time to cache a value. The filter here will cache a response for 10 seconds if the response indicates a success, otherwise it caches the response for 0 seconds, in this case the Polly code does not perform any caching.

1public void Configure(IApplicationBuilder app, IHostingEnvironment env,
2    IAsyncCacheProvider cacheProvider, IPolicyRegistry<string> registry)
3{
4    Func<Context, HttpResponseMessage, Ttl> cacheOnly200OkFilter =
5        (context, result) => new Ttl(
6            timeSpan: result.StatusCode == HttpStatusCode.OK ? TimeSpan.
7            slidingExpiration: true
8        );

The cache policy says that it caches HttpResponseMessages and uses the filter to decide if a response should be cached.

1IAsyncPolicy<HttpResponseMessage> cacheOnlyOkResponsePolicy =
2    Policy.CacheAsync<HttpResponseMessage>(
3        cacheProvider.AsyncFor<HttpResponseMessage>(), //note the .AsyncFor<HttpResponseMessage>
4        new ResultTtl<HttpResponseMessage>(cacheOnly200OkFilter),
5        onCacheError: null
6    );

Note the AsyncFor, this is very important. Thanks to Dylan Reisenberger for his help here, I spent too many hours trying to figure the overloads with no success.

Try it out in the provided solution, hit F5 and put some breakpoints in the controllers and on the filter in Startup.

That’s it, you now have selective caching of responses.

In the next post, I’ll show you how to cache the value inside the response instead of the whole response.  
Full source code here.

comments powered by Disqus

Related