Adding caching to WCF RESTful services using the REST Starter Kit

As promised, this is the first of a series of posts that intend to cover the new capabilities implemented in the WCF REST Starter Kit to enhance the development of RESTful services using WCF. Specifically, this post is focus on how to enable caching on RESTFul services by using the REST Starter Kit . Undoubtedly, caching is one of the greatest benefits of the Web programming model and one of the main attractive of REST  over alternatives such as SOAP/WS-*. Throughout the evolution of the web, the industry has developed very innovative techniques for optimizing content retrieval by the use of caching. These techniques have been reflected in technologies such as MemCache, Oracle Coherence and more recently Microsoft's Velocity that specialized in distributed caching. Additionally, web technologies like ASP.NET provides generic programming models that address some of the most common caching scenarios. All this infrastructure and technologies can be naturally leveraged by RESTful services without the need of creating new caching mechanisms.  Precisely, the REST Starter Kit leverages ASP.NET extending WCF RESTful services with caching capabilities.

The fundamental steps to add caching to a WCF RESTful service consists on adding the WebCache attribute to the operation intended to cache. The following code illustrates this concept on a simple WCF RESTful service which WAS NOT implemented using the WCF REST Starter Kit .

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class SampleService : ISampleService
{
    [WebGet(UriTemplate= "/results")]
    [WebCache(CacheProfileName = "SampleProfile")]

 public Atom10FeedFormatter GetData()
 {
      
        SyndicationFeed feed = new SyndicationFeed();
        feed.LastUpdatedTime = DateTime.Now;
        feed.Id = OperationContext.Current.Host.BaseAddresses[0].ToString()
                                          + "/" + Guid.NewGuid().ToString();
        feed.Title = new TextSyndicationContent("Sample feed");
        SyndicationItem item= new SyndicationItem();
        item.Title = new TextSyndicationContent( "sample feed" );
        item.Content= new TextSyndicationContent("Time: " +
                                                  DateTime.Now.ToString());
        item.Id= OperationContext.Current.Host.BaseAddresses[0].ToString()
                                          + "/" + Guid.NewGuid().ToString();
        item.LastUpdatedTime= DateTime.Now;
        List<SyndicationItem> items= new List<SyndicationItem>();
        items.Add(item);
        feed.Items = items;
        Atom10FeedFormatter formatter = new Atom10FeedFormatter(feed);
        return formatter;
}

 

As you can see, our sample operation is decorated with a WebCache attribute that references a specific caching profile. The details of the caching profile can either be configured as parameters of the WebCache attribute or as a configuration file section as illustrated in the following code.

<system.web>
  ...
      <caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <clear/>
          <add name="SampleProfile" duration="30" enabled="true"
                                                  location="Any" />
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

  ...
</system.web>

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
   
  <services>
   <service name="SampleService"
                              behaviorConfiguration="ServiceBehavior">
    <!-- Service Endpoints -->
    <endpoint address="" binding="webHttpBinding"
                                             contract="ISampleService">
  
     …
    </endpoint>
   </service>
  </services>
  <behaviors>
   ...
  </behaviors>
</system.serviceModel>

The configuration detailed above instructs ASP.NET to cache the results of the operation for thirty seconds. We can corroborate this by querying the following URI multiple times and checking the date returned in the Atom entry.

Although some scenarios might require different caching techniques, this model extend all the benefits of the ASP.NET caching programming model into WCF RESTFul services which directly a large variety of the most common caching use cases in real world REST-based solutions.

How does this work?

From the WCF programming model standpoint, the WebCache attribute is implemented as a WCF operation behavior.

[AttributeUsage(AttributeTargets.Method)]
public sealed class WebCacheAttribute : Attribute, IOperationBehavior
{
…Implementation omitted…

public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
{
    …Implementation omitted…

    dispatchOperation.ParameterInspectors.Add(
                                      new CachingParameterInspector(…));
}
}

When the host initializes the behavior adds an instance of the CachingParameterInspector class to the dispatcher parameter inspector's collection.  Ultimately, is this parameter inspector which executes the caching algorithms by leveraging the ASP.NET infrastructure.

If you are interested on getting deep into the things you can achieve with the WCF REST Starter Kit make sure you check the Hands On Labs available here.

No Comments