Okay, WCF, we can be friends now
Over the years, I've had a tough time with Windows Communication Foundation, otherwise know as (and sometimes cursed as) WCF. I knew it was what I was "supposed" to be using to because it handled complex scenarios like managing access as secured messages passed through systems and users with different access rights. However, it didn't seem to be able to handle my simple scenarios – things like returning very simple, unrestricted information from a server to a client – without requiring hours of pain, configuration, and things like writing a custom ServiceHostFactory.
I understand the idea of WCF – it’s an entire API that’s designed to allow for just about anything you might want to do in a SOA scenario, and it offers a pretty big abstraction over the transport mechanism so you can swap out SOAP over HTTP to Binary over TCP with a few well-placed config settings, and you can theoretically do it without caring about the transport or wire format.
So, I guess my thoughts on WCF up until very recently can be summed up as follows:
- I knew it did a lot of neat, advanced things that I never seemed to need to do
- WCF configuration always seemed to be a problem for me in rather simple use, e.g. hosting a basic, unauthenticated WCF service in an MVC application on shared hosting
- My co-workers got sick of trying to explain to me why I shouldn’t just use an ASMX service
All that’s changing, though. There have been two new developments in WCF-land that have broken down the walls I’d built around my heart:
- WCF 4.0 took a first step to making simple things simple by defaulting to “it just works” mode. For example, when you create a service that uses HTTP transport, it uses all the same settings you’d get with an ASMX service unless you go in and explicitly change them. That’s cool.
- The really big news – Glenn Block’s PDC 2010 announcement of the new WCF Web API’s.
Favorite new features in WCF Web API’s
Focus
First, the overall focus on HTTP as a good thing, not something to be abstracted away. There can be value in a variety of approaches, and those values can shift over time. WCF’s original design seemed to be oriented towards letting coders write code without worrying about the transport protocol. That can be useful in cases, but the fact is that HTTP contains some great features that we’ve been ignoring. This seems a little similar to the difference in approaches between ASP.NET Web Forms / ASP.NET MVC. In some cases an abstraction can help you be more productive by handling insignificant details for you, but in other cases those details are significant and important.
And I think the variety in focus is a good thing. Different software challenges call for different tools. For instance, looking at the WCF offerings:
- WCF Data Services is a great way to expose data in a raw format which is queryable and accessible in a great, standards friendly format (OData)
- WCF RIA Services solves some common client-server communication issues, such as keeping business logic in sync on both client and server through some pretty slick cross-compilation
- [more WCF options here – IANAWE (I am not a WCF Expert)]
- Now, WCF Web API’s provide an option for writing pure, RESTful services and service clients that work close to the HTTP level with minimal friction
Pipeline
Rather than stack piles of attributes on your service methods or write a ton of configuration, you can surgically process the input and output using lightweight processors. For instance, you can create a processor that displays information for a specific media type, like JSON or an image format like PNG. What’s really powerful here is that these processors can be associated with a media type, so they’re automatically returned to clients of your service based on what media types they prefer, as stated in the Accept header.
More on that in the next post, where I talk about using the Speech API to create a SpeechProcessor that responds to clients which accept audio/x-wav.
Queryable services
Glenn’s announcement post shows the promise here – you can simply annotate a service with the [QueryComposition] which will allow clients to query over a service’s results. Glenn’s post shows how this works pretty well, so I’m just quoting it here. First, a service is marked as queryable:
[WebGet(UriTemplate = "")] [QueryComposition] public IEnumerable<Contact> Get() { return contacts.AsQueryable(); }
Now we can query over the results on the client. For instance, if we wanted to get all contacts in Florida, we could use a request like "http://localhost:8081/contacts?$filter=State%20eq%20FL" which says "find me the contact with a State equal to FL".
Client-side Features
There are some great client-side features which mirror new features on the server-side. For instance, once your services are exposed as queryable, there’s client-side support for query via LINQ. There’s support via HttpRequestMessage and HttpResponseMessage to the HTTP values on the client as well as on the server.
The new HttpClient provides a client which was built with the same philosophy and API support on the client to match what’s on the server. I’ll plan to look at HttpClient first when I need to query services from .NET code.
WCF jQuery Support
There’s some interesting work in progress to build out support for writing services which are accessible from jQuery. While I’d probably use ASP.NET MVC’s JSON support for simple cases, if I needed to build out a full API which exposed services over AJAX, this looks really useful.
JsonValue
The jQuery support gets even more interesting with new support for JsonValue. Tomek spells it out in a great post covering WCF support for jQuery, but I think broad support for JsonValue in the .NET Framework deserves some individual attention because it enables some really slick things like LINQ to JSON:
JsonObject body; string[] favoriteToys = (from child in (JsonValue)body.AsDynamic().Children where child.Value.AsDynamic().Name.ReadAs<string>(string.Empty).StartsWith("J") select child.Value.AsDynamic().BestToy.ReadAs<string>("No favorite toy")).ToArray();
Where to go next
There’s a lot to the new WCF Web API’s, and I’m only scratching the surface in this overview. Check out my next post to see a sample processor, and take a look at the list of posts listed in the News section at http://wcf.codeplex.com/ for more info.
Some top resources:
- http://wcf.codeplex.com
- Glenn’s talk at PDC: Building Web API’s for the Highly Connected Web
- Glenn’s announcement blog post: WCF Web API’s, HTTP Your Way
- Darrel Miller’s overview: Microsoft WCF Gets Serious about HTTP