An expanded Web Programming Model is now available in Windows Communication Foundation (WCF) 3.5. This Web Programming Model allows developers to build Services using a RESTful architecture. Services built using this new architecture approach is growing significantly. This Talking Point will cover the basics of REST versus SOAP/WS-*, and how to build Services using WCF 3.5 based on REST. We also cover Web feeds (RSS and/or ATOM) for Services to enable easy access to enterprise data (see ADO.NET Data Services to see this technology applied to Data Services).
REST
REST is an architectural style that derives from the client-server architectural style. The basic premise of REST is to build client-server applications using the same principles that the World Wide Web is built on. The main concept behind REST as an architectural style is to follow the best practices of the web.
The constraints of REST are based on the idea that clients interact with resources (representations of data that we want to work with). Each resource is identified by a unique URI. We interact with resources by addressing the URI and using a uniform interface to tell the service what we want to do with a resources. Other constraints are that services should be stateless (to increase scalability), and that resources should have links to other resources and those links can drive the state of the application.
The basic premise of REST is to build client-server applications using the same principles that the World Wide Web is built on. (HTTP Methods):
- GET is used to get a resource.
- POST is used to create a resource, and is considered “un-safe” – it will likely have side effects.
- PUT is used to update a resource, and
- DELETE is used to delete a resource.
- (others)
Microsoft has adopted REST as a first class approach to Web Programming, examples of that are:
- Microsoft Live Services
- ADO.NET Data Services
- SQL Server Data Services
- Cloud (Azure, .NET Services)
The reasons and benefits are many but mainly:
- It fits well when building wide open systems when you don’t control or even know who the clients are going to be). The wide interoperability and caching capabilities are key. The emphasis on a stateless service implementation enabling scalability through web farming.
- There isn’t a new interface to be learned for each service. The uniform interface allows a developer to concentrate on the URI and the resource representation.
Building a RESTful Service involved 4 high-level steps:
- Determine what your resources are going to be (Orders, Customers, etc.) and determine what content-type(s) will represent those resources.
- Design your URI structure. For example, your collection of orders could be /orders, and each individual order could be /orders/{orderid}.
- For each resource, determine what part of the HTTP uniform interface to implement.
- You also need to determine how your resources link to each other (Hyperlinking).
WCF
WCF is a core building block within out platform for building systems that communicate over networks. It is built as an open framework that supports many styles of applications, like client-server, message oriented, or service oriented, etc. It abstracts away from the developer all the complexity of networked systems, so developers can focus on the business logic.
Although the underlying message model is based on the SOAP message format, with a Header and a Body, building RESTful services as possible with WCF even before .NET 3.5 (with considerably more plumbing code), but it is a testament of WCF’s truly open and extensible design.
With 3.5, WCF added both infrastructure support (bindings, etc.) as well as a programming model.
In ServicePack1 the team added:
- Support for AtomPub’s ServiceDocument and CategoriesDocument
- Support for characters inside of path segments (/{lat};{long} )and file extensions (/{name}.json)
- and more…
This make building RESTful endpoints with WCF very straightforward, even if you don’t know a lot about REST.
AJAX
AJAX (Asynchronous JavaScript and XML), is a very popular way to build rich web applications. Although conceived as XML-based, most AJAX applications today use JSON (JavaScript Object Notation).
JSON has a smaller serialization footprint and saves bandwidth and processing. It also has a natural integration with JavaScript (through the eval function), and so the programming experience in JavaScript is much nicer.
On top of the base functionality WCF has additional support for building AJAX-based applications. First, there is a serializer that will take .NET objects and turn them into JSON, or take JSON objects and turn them into .NET objects. Also, if you are using ASP.NET AJAX as the client programming model, there is a JavaScript “proxy” which is exposed from the endpoint that enables you to use the service endpoint with very little effort, and has the added benefit of integrating with ASP.NET’s IntelliSense in Visual Studio.
WEB FEEDS and WCF
Feeds are a common way of exposing data on the web, particularly to automate posting machine-readable data for blogs and news. Organizations are finding feeds to be a very useful way to also expose various types of enterprise data. For instance, almost all of the data in a SharePoint portal can be exposed as a feed.
Syndication, the act of exposing data using web feeds relies in two typical formats: RSS and Atom. RSS is the older standard, and Atom is quickly become the more dominant (although many sites/endpoints expose both formats) because Atom has a richer model for non-HTML data as well as linking.
The support built into WCF for feeds is built on top of the base functionality we mentioned above.
The basic idea behind the WCF support for feeds it to abstract away from the developer the need to know the various feed formats (in this version of WCF that’s RSS 2.0 and Atom 1.0). This is done by separating the data from the serialization model.
Developers can simply take data and push it into the WCF OM (Object Model). Then take the WCF OM and pass it to the formatter. The formatter takes care of turning the WCF OM (which is layered on top of the data) into the correct feed format.
The WCF OM is closer to the Atom model, since the Atom model is as we said before, a little richer in terms of its data.
Finally, the WCF object model from WCF relies in two core objects: SyndicationFeed and SyndicationItem. The SyndicationFeed represents the whole feed, and each SyndicationItem represents an entry. SyndicationFeed has an Items property which holds onto the individual items.
In Part II we will explore:
- WCF Dispatching
- AtomPub
- Tooling support
- Security
- Processing
- Transactions
- Purity (Purists vs Pragmatics)
Conclusion
REST as an architectural style encourages interoperable, scalable web services, while WCF 3.5 provides the support for building services using this architectural style. Building RESTful services in .NET is an elegant integration of simplicity and power. We leverage the simplicity of the fundamental web protocols with the power of our framework and development tools.
References
- Check Soap & RESTful Services on Channel9
- MSDN REST Resources
- Windows Communication Foundation REST Starter Kit
In Part I we saw how WCF has been extended to support RESTful services natively! We discussed how the primitive constructs of the web (HTTP Methods) enable communication patterns that are simple yet very flexible and powerful. We saw how WCF serves as the building block within our platform to extend services to the cloud. We also explored the role of AJAX and Web Feeds (RSS, Atom) in enabling a new programming model that builds upon the progress achieved in making the web a programmable environment.
This time we will focus on some of the mechanics that make it all work with general observations on additional aspects of the technology.
WCF Dispatching
We already know that WCF’s main purpose is to abstract away network and security and allow developers to concentrate on writing code. A developer writes code inside of methods on what is commonly known as the “service type”.
WCF, by default, routes network messages to these methods based on the SOAP Action header. This is done by the “dispatching layer” in WCF which is responsible for figuring out what method to call when a network message arrives.
WCF implements SOAP using the standards, with one URI for each service endpoint. In WCF 3.5, a new dispatcher is added which dispatches based not on SOAP action, but instead based on the URI + the HTTP Verb. This allows a WCF endpoint to implement a RESTful approach, because in REST we expose resources at specific URIs that respond to particular HTTP verbs.
By annotating methods with new attributes, the new WCF dispatcher is able to route messages coming into particular URIs to particular methods, based on the verb of the request. All the other familiar WCF programming model constructs are the same. In fact, in some cases WCF definitions can be used with both SOAP and REST endpoints.
In a typical WCF service endpoint we have messages coming in from some network protocol. WCF allows us to plug in different protocols (like HTTP, MSMQ, TcpIP) along with different protocol channels (like WS-Security, WS-ReliableMessaging, etc). The MessageEncoder is responsible for taking the network message format (which might be XML or even binary) and turn it into something that WCF can understand. The dispatcher then gets involved and figures out what method to call on the classes you write.
The Web dispatching layer reduces this down to the HTTP transport channel, the TextMessageEncoder (with MessageVersion set to none – which effectively turns off the SOAP envelope), and then the new dispatcher. So when messages arrive for a particular URI, a match is made to one or more methods, and then the verb is checked. If a match is made, the message is then passed to that appropriate method.
WCF 3.5 REST basics summary
- UriTemplate: Literal and replaceable path URI path segments
- This allows URIs to be declared with both literal and replaceable path segments (like /users/{userid}). We use this syntax to tell WCF what URIs we want our methods to respond to, with the replaceable path segments passed into our methods as parameters.
- This allows URIs to be declared with both literal and replaceable path segments (like /users/{userid}). We use this syntax to tell WCF what URIs we want our methods to respond to, with the replaceable path segments passed into our methods as parameters.
- WebGetAttribute: Verb GET - UriTemplate property defines URI andWebInvokeAttribute: Verb * - Method property (POST is default)
- WebGetAttribute, and WebInvokeAttribute, that get placed on our WCF OperationContract methods. The WebGetAttribute tells WCF that a particular method should respond to GET requests. The WebInvokeAttribute defaults to POST, but can be customized via its Method property to use the other verbs in the uniform interface. Both WebGetAttribute and WebInvokeAttribute have a UriTemplate property to allow customization of the URI at the method level.
- WebGetAttribute, and WebInvokeAttribute, that get placed on our WCF OperationContract methods. The WebGetAttribute tells WCF that a particular method should respond to GET requests. The WebInvokeAttribute defaults to POST, but can be customized via its Method property to use the other verbs in the uniform interface. Both WebGetAttribute and WebInvokeAttribute have a UriTemplate property to allow customization of the URI at the method level.
- WebHttpBehavior: Replaces dispatcher (HTTP + VERB)
- Endpoint behavior that replaces the default SOAP dispatcher (the one based on SOAP:Action) with the one that does the dispatching based on URI+Verb
- Endpoint behavior that replaces the default SOAP dispatcher (the one based on SOAP:Action) with the one that does the dispatching based on URI+Verb
- WebHttpBinding: HTTP+TEXT (no soap)
- Creates a WCF channel stack with just the HTTP transport and the TextMessageEncoder, with MessageVersion set to None
- Creates a WCF channel stack with just the HTTP transport and the TextMessageEncoder, with MessageVersion set to None
- WebServiceHost/WebServiceHostFactory: Automatic config/Automatic config in IIS
- A custom ServiceHost-derived class that can automatically configure RESTful endpoints, and WebServiceHostFactory is a ServiceHostFactory-derived type that can be used in managed (IIS) hosted scenarios.
AtomPub
The support built into WCF for feeds is of course built on top of the base functionality we discussed on Part I. Typically, we use WebGet to expose a feed endpoint from a particular URI. The basic idea behind the WCF support for feeds it to abstract away from the developer the need to know the various feed formats (in this version of WCF that’s RSS 2.0 and Atom 1.0). This is done by separating the data from the serialization model.
As a developer, I can simply take my data and push it into the WCF OM. I then take the WCF OM and pass it to the formatter. The formatter takes care of turning the WCF OM (which is layered on top of my data) into the correct feed format.
The WCF OM is closer to the Atom model, since the Atom model is as we said before, a little richer in terms of its data. AtomPub is quickly becoming a common way to expose a RESTful service when the resources fit the AtomPub model (collections of collections of things). It’s been adopted by Google and Microsoft Live as the way to expose their services functionality.
3.5 SP1 adds support for:
- ServiceDocument (which is the top-level document in an AtomPub endpoint, which contains one to n workspaces. A workspace can indicate things like what media types a collection can accept, as well as just providing an organizational structure around a set of feeds.
- CategoriesDocument (that contains the list of official categories or tags for a collection).
Tooling support
Its clear that SOAP/WS-* has the advantage in the tooling area. This is because SOAP services can expose WSDL and Policy information that client tools can easily consume to build proxies. On the REST side there are two competing camps. One camp wants to create RESTful metadata, and so there are open projects like WADL (Web Application Description Language) out there, and some people feel that WSDL 2.0 can be used to describe RESTful services.
ADO.NET Data Services, a full REST-based data service, exposes metadata, but it isn’t in any sort of a standard and only works with “Add service Reference”.
The other camp believes that metadata-generated clients causes too much coupling between a client and service. For this camp, the hypermedia constraint is extremely important in building loosely coupled clients that can get the “root” resource from a service and then just drive off of the links in that resource.
Security
Security is something you often hear is better in the SOAP world. Of course WS-* does provide for end-to-end message level security across transports – but in the wild you generally find people using SOAP over HTTP, and often times using SSL.
Since REST is built on the framework of the Web, it can simply use the same security model you use on the Web. Typically that is SSL, using either basic or certificate authentication.
Federated security is another emerging technology, and the WS-* side has an lead in that area, but there are emerging standards in the web world as well (OpenId and OpenAuth), and likely federated solutions will support both (.NET Services identity services support both SOAP and REST clients).
Processing / Transactions
Another issue that comes up is the feeling that REST is really just about CRUD. Certainly CRUD maps well onto the uniform interface, and when learning REST this is generally the way people think about REST. They have a hard time thinking about more than CRUD.
Generally the canonical example of a bank account represented as a resource makes sense to people. But what happens when you throw a transfer scenario onto that service? This is where people tend to feel more comfortable with RPC (like SOAP).
The way people in the REST camp look at this problem as one of refactoring your resources. Instead of creating a “method” for an account transfer – you create a “transfer” resource. The resource is a temporary resource that represents the transfer. Since REST has no notion of transactions this also makes some people nervous, and the idea of conditional PUT (using etags) can provide protection against processing the transfer more than once.
Service Consumption
How do you consume RESTful services using .NET?
HttpWebRequest/HttpWebResponse is one way to go (and probably *the* way to go if you are in the hypermedia/loosely coupled camp). Although you generally have to program at a pretty low level, using the DataContract or XmlSerializer to create request bodies and read responses.
WCF’s programming model is symmetrical, and works as a client programming model as well. But since there isn’t any support for metadata, you have to hand code all of the interfaces. You can generate type definitions by using Visual Studio’s XML functionality (to infer a schema from an XML instance, and then use WCF’s svcutil to generate a class definition).
When consuming feeds you can use the WCF SyndicationFeed class (or ServiceDocument if you are consuming AtomPub). In the AJAX scenario of course there is the auto-generated client.
Purity (Purists vs Pragmatics)
The Purist problem is one that actually makes some people turn away from REST. There are a number of people out there that are very religious about REST and are very vocal about critiquing people they think are doing REST *wrong*.
What’s really important is to understand the architectural style and constraints of REST and what advantages each of them provide. If you decide to build a service using most, but not all, of the constraints as long as you understand what you are giving up in exchange for ignoring one or more of the constraints you still will be taking advantage of the features of the other constraints.
Some developers may refer to “Lo-REST” and “Hi-REST”, where Lo-REST is sort of pragmatic and Hi-REST is more pure. We won’t get into it here :-)
Conclusion
Fortunately we live in a universe of endless diversity (so it seems!) from stars to cereals! So it should be natural to expect the same pattern reflected in everything we do in IT from programming languages to distributed communication methods. REST, as we have seen, serves to further expand the diversity already present in WCF, and therefore our platform; to provide the flexibility necessary to enable Cloud computing and Software + Services. This trend will evolve into a mature new platform where diverse systems and solutions are connected together in meaningful ways targeted at the specific needs of everyone.
References
For everything RESTful in WCF go to MSDN here is the source. and for everything REST on channel 9 here is the full collection.
Have a RESTful week!
Joel Reyes