REST in WCF – Part IV (HI-REST – Exposing a service via GET – Configuring the service)
In part I of this series, I gave a brief overview of REST and put forth the concept of the REST continuum. I made the case that differing folks had differing views on what REST is and that is ok. I put forth the case that these differing definitions of REST made up a continuum of sorts, with one end being LO-REST and the other HI-REST. In parts II and III, I introduced the webHttpBinding, a new binding to WCF 3.5 (part of Fx 3.5 that installs with VS 2008). I discussed that this is the binding that now allows us to expose services RESTfully. I noted that when working with this binding, your endpoint must have a behaviorConfiguration that ties it to one of two endpoint behaviors: enableWebScript and webHttp. I pointed out that the enableWebScript endpoint behavior was an AJAX-Friendly implementation of the webHttp endpoint behavior (it is actually a subclass). Lastly, I build a sample utilizing the AJAX-Friendly endpoint behavior (enableWebScript) and postulated that this type of implementation was RESTful and fell along the LO side of the continuum.
In this post and the following few, I will introduce the features of the webHttp endpoint behavior. I will illustrate how you can take advantage of these features to implement services that fall on the HI-REST end of the continuum. Specifically, in today’s post, I will illustrate the GET functionality.
Adding the Service
Unfortunately, there is not an out-of-the-box template for a service taking advantage of the webHttpBinding and the webHttp endpoint behavior. Keeping in mind the fact that templates are not magic and simply add specific files and update others, you can use either the ‘AJAX-enabled WCF Service’ or the ‘WCF Service’ template and make the appropriate changes. For the purpose of this post, I will use the latter.
The first step is to add our new service, using the ‘WCF Service’ template. I am going to call the service RESTCatalogService. To do this, Right-Click on the project (in Solution Explorer) > Choose ‘Add New Item’ > Choose ‘WCF Service’ > Name it RESTCatalogService.svc > click ‘Add’.
As you might imagine, this template is quite similar to the ‘AJAX-friendly WCF service’ template we used in part II. As I did in that post, I will list the files that were created or updated by the template. They are as follows:
- Adds a RESTCatalogService.svc file to the project root
- Adds a IRESTCatalogService.cs file in the app_code
- Adds a RESTCatalogService.cs
- Configures the service in the web.config
Examining the files
Lets take a look at each of the files created by the template and discuss briefly. In this post, I’ll look at #s 1 and 4. In tomorrows, we’ll look at 2 & 3. Here goes:
<%@ ServiceHost Language="C#" Debug="true" Service="RESTWineService" CodeBehind="~/App_Code/RESTWineService.cs" %>
This file was described adequately in part II and is no different here, so I will not duplicate that effort here.
We are going to have to make some major modifications to the entries made by the ‘WCF Service’ template. For clarity sake, let’s take a look at the configuration set up by that template (I have made some annotations to help clarify:
The following should help provide a little context around the drawing above, as well as describe the changes we will be making:
Part II – Everything marked ‘Part II’ was added to the web.config in Part II of this blog series, illustrating AJAX-Friendly services. We will simply leave these configurations alone.
serviceBehaviors node – The serviceBehaviors node contains one behavior with SOAP-Specific configurations. For instance, the serviceMetadata node controls whether or not metadata publishing services are enabled. We do not publish metadata for services exposed using the webHttpBinding. We will delete this node and it’s children.
identity node – The identity node represents the security identity of the service. The identity node does not apply to the webHttpBinding binding. You will note that it does apply to the the default binding that was added here, the wsHttpBinding. We will delete this node and it’s child.
endpoint address="mex" – Services are able to publish their metadata via a metadata exchange endpoint. This endpoint is where the metadata is exposed. It was added for the default wsHttpBinding. It will serve out the WSDL that will allow tools such as SvcUtil.exe (used under the hood by Visual Studio) to automatically generate a client proxy that abstracts away the complexity of calling the service. However, there is no agreed upon format for metadata surrounding RESTful services. Therefore, the webHttpBinding does not support serving metadata. We will delete this node and it’s child.
binding="wsHttpBinding" – The default binding added by the ‘WCF Service’ template is the wsHttpBinding. This binding supports advances web service standards such as addressing, transactions, reliable messaging, among others. We will change this to our REST-Friendly binding of webHttpBinding.
serviceHostingEnvironment – This element defines the type the service hosting environment instantiates for a particular transport. The aspNetCompatibilityEnabled attribute configures whether ASP.NET compatibility is on or off. If this is set to true, then the WCF service will flow through the ASP.NET pipeline, giving it access to things like ASP.NET context and session state. We are going to delete this node.
missing endpoint behavior – We are going to have to add a "RESTFriendly" endpoint behavior similar to the AJAXFriendly configuration. The difference being that the RESTFriendly behavior will have a child webHttp element. This endpoint behavior will allow us a great deal of freedom when defining the REST endpoint.
The following is the new configuration for our service:
<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="AJAXFriendly"> <enableWebScript /> </behavior> <behavior name="RESTFriendly"> <webHttp /> </behavior> </endpointBehaviors> </behaviors> <services> <service name="CatalogService"> <endpoint address="" behaviorConfiguration="AJAXFriendly" binding="webHttpBinding" contract="CatalogService" /> </service> <service name="RESTCatalogService"> <endpoint address="" behaviorConfiguration="RESTFriendly" binding="webHttpBinding" contract="IRESTCatalogService" /> </service> </services> </system.serviceModel>
All of the changes detailed in the previous list may seem a bit complex. This is mainly due to the fact that there were a host of configuration settings made with the wsHttpBinding in mind. As it turns out, the HI-REST Friendly configuration settings are quite simple and can be boiled down to 3 (all bolded above):
- Set the binding in your endpoint to webHttpBinding
- Add a behavior under the endpointBehaviors element that has a webHttp child element
- Add a behaviorconfiguration to your endpoint that references the endpoint behavior added in step 2.
Well, we have done the hard part, configured our service. In the upcoming REST toolkit, we will have a template that greatly eases this process. Tomorrow, we will look at the ServiceContract (in IRESTCatalogService.cs) and the implementation (in RESTCatalogService.cs).