It has been a week or so since I contributed to my series on WCF 3.5. Hopefully, I will get things back on track this week by focusing a bit on the new features that support the REST style of web services. Rather than going into a long winded explanation of REST, I will defer to Wikipedia's definition. The key take away for the purpose of this post is that REST is an alternative to the WS-* protocols and SOAP. It places more of an emphasis on Plain Old Xml (POX) and HTTP methods (or verbs).
We will kick things off by taking a look at one of the new attributes in WCF. For those of your REST guys, this will be one of the most commonly used attributes for your services. It is none other than WebGet, which resides in the System.ServiceModel.Web assembly. As the name implies, this provides a mechanism to map an HTTP GET operation to a specific method.
Let's look at a simple example and break it down:
[ServiceContract(Namespace = "http://JeffBarnes.Samples.WeatherService")]
public interface IWeatherService
{
[OperationContract]
[WebGet(
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml,
UriTemplate = "/GetCurrentTemp/{zipCode}")]
Temperature GetCurrentTemperature(string zipCode);
}
If you examine the code, you will see a typical service contract and operation contract. However, the WebGet attribute has also been applied to the same method as the operation contract. This notifies the WCF runtime that the method is a retrieval operation and can be mapped to an HTTP GET operation. The Temperature class returned by the method is a very simple class that contains a Scale and Amount property. It is exposed via a standard DataContract.
As you can see, there are a few parameters available in the attribute. They are relatively self-explanatory, but let's quickly review them.
BodyStyle
This parameter indicates whether the request and response should be wrapped with "infrastructure provided XML elements." This wrapping can be applied to both the request and response or only one of the two. When set to Bare, there is no wrapping provided.
Here is an example of a wrapped response from the GetCurrentTemperature method.
<GetCurrentTemperatureResponse xmlns="http://JeffBarnes.Samples.WeatherService">
<GetCurrentTemperatureResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Amount>10.25</Amount>
<Scale>Celsius</Scale>
</GetCurrentTemperatureResult>
</GetCurrentTemperatureResponse>
Here is an example of a bare response from the GetCurrentTemperature method.
<Temperature
xmlns="http://JeffBarnes.Samples.WeatherService"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Amount>10.25</Amount>
<Scale>Celsius</Scale>
</Temperature>
RequestFormat and ResponseFormat
These two parameters simply specify whether the request and response will be formatted as Xml or JSON. Since there are two separate parameters, you could potentially have the request formatted differently from the response.
UriTemplate
At last, we finally begin to see where the new UriTemplate class comes into play. This template provides a way to map the zip code in the uri to the zip code parameter in the GetCurrentTemperature method. The beauty of this is that WCF takes care of the dirty work. Rather than manually parsing out parameters from a uri, WCF just hands the value to the method. Refer to my previous post about UriTemplate for more information.