We all know hitting the database is an expensive operation, adding the cost of serialization on top of that means that caching the output makes even more sense. The fact that WCF Data Services is built on top of the ASP.net platform means you can utilize all of its power to help you build a better service. This post examines the ASP.net output caching and how one would use it on WCF Data Service. Cache Variation and Static Service Caching
ASP.net applications has the ability to cache the generated output on the server side. When a next matching request comes in, the output will then be delivered straight from the cache, rather than invoking the handler (calling data service). Note that this behavior applies to GET requests only. Note the word “matching” requests. How we match an request to a cached item is essential to delivering correct data to the customers. For a static (non-updating, we’ll take a look at caching for writable services too) WCF data service endpoint, the output will change depending on the URI path, all of the query parameters, and headers as well (accept, charset, etc.). ASP.net output caching has this notion of “VaryBy…”, which essentially means how we match incoming requests to items in the cache table (of course, non-matching items are added to the table). MSDN has an article that discusses asp.net caching in detail, so I won’t repeat what the parameters are here. Let’s setup our example using a standard Northwind service over Entity Framework, everything is very standard at this point:namespace DataServiceCache
{
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class NorthwindService : DataService<NorthwindEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.UseVerboseErrors = true;
}
}
}
Next, we override the OnStartProcessingRequest method to set the cache policy:protected override void OnStartProcessingRequest(ProcessRequestArgs args)
{
base.OnStartProcessingRequest(args); HttpContext context = HttpContext.Current; // set cache policy to this page
HttpCachePolicy cachePolicy = HttpContext.Current.Response.Cache; // server&private: server and client side cache only
cachePolicy.SetCacheability(HttpCacheability.ServerAndPrivate); // default cache expire: never
cachePolicy.SetExpires(DateTime.MaxValue); // cached output depends on: accept, charset, encoding, and all parameters (like $filter, etc)
cachePolicy.VaryByHeaders["Accept"] = true;
cachePolicy.VaryByHeaders["Accept-Charset"] = true;
cachePolicy.VaryByHeaders["Accept-Encoding"] = true;
cachePolicy.VaryByParams["*"] = true; cachePolicy.SetValidUntilExpires(true);
}
We assume that this service is static here, (never changes shape), so we set the expire date to never expire (although ASP.net should auto adjust this back to expire in 1 year). Fire up the service now to test the cache – one indicator of whether the feed is cached is by examining the “Updated” timestamp.
Read more: public Blogger SPQ;
ASP.net applications has the ability to cache the generated output on the server side. When a next matching request comes in, the output will then be delivered straight from the cache, rather than invoking the handler (calling data service). Note that this behavior applies to GET requests only. Note the word “matching” requests. How we match an request to a cached item is essential to delivering correct data to the customers. For a static (non-updating, we’ll take a look at caching for writable services too) WCF data service endpoint, the output will change depending on the URI path, all of the query parameters, and headers as well (accept, charset, etc.). ASP.net output caching has this notion of “VaryBy…”, which essentially means how we match incoming requests to items in the cache table (of course, non-matching items are added to the table). MSDN has an article that discusses asp.net caching in detail, so I won’t repeat what the parameters are here. Let’s setup our example using a standard Northwind service over Entity Framework, everything is very standard at this point:namespace DataServiceCache
{
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class NorthwindService : DataService<NorthwindEntities>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.UseVerboseErrors = true;
}
}
}
Next, we override the OnStartProcessingRequest method to set the cache policy:protected override void OnStartProcessingRequest(ProcessRequestArgs args)
{
base.OnStartProcessingRequest(args); HttpContext context = HttpContext.Current; // set cache policy to this page
HttpCachePolicy cachePolicy = HttpContext.Current.Response.Cache; // server&private: server and client side cache only
cachePolicy.SetCacheability(HttpCacheability.ServerAndPrivate); // default cache expire: never
cachePolicy.SetExpires(DateTime.MaxValue); // cached output depends on: accept, charset, encoding, and all parameters (like $filter, etc)
cachePolicy.VaryByHeaders["Accept"] = true;
cachePolicy.VaryByHeaders["Accept-Charset"] = true;
cachePolicy.VaryByHeaders["Accept-Encoding"] = true;
cachePolicy.VaryByParams["*"] = true; cachePolicy.SetValidUntilExpires(true);
}
We assume that this service is static here, (never changes shape), so we set the expire date to never expire (although ASP.net should auto adjust this back to expire in 1 year). Fire up the service now to test the cache – one indicator of whether the feed is cached is by examining the “Updated” timestamp.
Read more: public Blogger SPQ;
0 comments:
Post a Comment