I am designing a distributed application that will consist of RESTful services and a variety of clients (Silverlight, iOS, Windows Phone 7, etc). Right now I'm determining which technology I should use to implement my services, WCF Data Services (OData) or the new ASP.NET Web API that's coming out with ASP.NET MVC 4.
I've watched a few presentations online about each and right now I'm leaning towards WCF Data Services primarily because of the filtering mechanisms built into the URI and native hypermedia capability. The only downside I can see is the verbosity of the Atom Pub specification as opposed to POX.
Is there anything I should know about these two technologies before making a decision? Why would someone choose ASP.NET Web API over WCF Data Services?
There are currently other major differences between WebApi and WCF Data Services, which no one ever seems to mention. I wish MS would come out with a good article comparing the two.
I've been following OData for a while and also WebApi. I've always found a few major distinctions.
First, I'm not sure what your boss means by "MS is backing WebApi", as to mean they aren't backing OData?? IMO, they are backing both and currently there is some minimal overlap. Windows Azure Data Market exposes their Data using OData, Azure Table Storage uses OData, SharePoint 2010 allows OData Queries over it's Data, and other Products from MS are also supporting it, such as Excel PowerPivot. It's a very powerful Query framework when it comes to relational Data. And because it's RESTful, any language, framework, device, etc can integrate with it.
Here is what I like about OData + WCF Data Services:
OData + WCF Data Services has finally allowed Client Applications to be more "expressive" when querying Data over the Web. Before, we always had to use ASMX or WCF to build rigid Web APIs which get unwieldly and require constant changes whenever a UI wants something slightly different. The Client Application could only specify parameters to dictate what criteria to return. Or do like I did and "Serialize" LINQ Expressions and pass those as the Parameters and re-hydrate into Expressions<Func<T,bool>>
on the Server. Its decent. Got the job done, but I want to use LINQ on the Client and have it translated over the Web using REST, which is exactly what OData allows and I don't want to use my own "hack" of a solution.
It's like exposing "TRANSACT SQL" without the need of a DB Connection String. Simply provide a Url and whoala! Start querying. Of course, both WebApi and WCF Data Services support Authentication/Authorization, so you can control access, append additional "Where" statements based on roles or other data configuration. I'd rather do this in my Web Api Layer than in SQL (like building Views or Stored Procs). And now that Applications can build queries themselves, you'll see Ad-Hoc and BI Reporting tools starting to leverage OData and allow Users to define their own results. Not relying on Static Reports where they have minimal control.
When developing in Silverlight, Windows 8 Metro, or ASP.NET (MVC, WebForms, etc), you can simply add a "Service Reference" in Visual Studio to the WCF Data Service and quickly start using LINQ to query Data AND you get a "Data Context" on the Client, which means it tracks changes and allows you to "Submit" your changes atomically back to the Server. This very similiar to RIA Services for Silverlight. I would have used WCF Data Services instead of RIA Services, but at the time, it did not support DataAnnotations or Actions, but now it does :) WCF Data Services has another advantage over RIA Services, which is the ability to perform "Projections" from the Client. This can help with performance, incase I don't want to return all Properties from an Entity. Having a "Data Context" on the Client is great when dealing with Line-Of-Business Apps.
So, WCF Data Services is great if you have Data with relationships, especially if you are using SQL Server and Entity Framework. You'll quickly be able to expose Queryable Data + Actions (calls to invoke operations, i.e. workflows, background processes) over REST with very little Code. WCF Data Services was just updated. New release launched. Check out all the new functionality.
The downside to WCF Data Services is the "control" you loose over the HTTP Stack. I found the biggest flaw was in the IQueryable<T>
Methods which return Collections. Unlike RIA Services AND WebApi, you DON'T have full access to develop the logic in the IQueryable Method. In RIA Services and WebApi, you can write whatever code you want as long as you return IQueryable<T>
. In WCF Data Services, you ONLY get access to append a "Where" Statement using Expression<Func<T,bool>>
interceptor Methods. I found this disappointing. Our current application uses RIA Services and I find we really need the ability to control the IQueryable logic. I hope I'm wrong on this and I'm just missing something
Also, WCF Data Services does NOT yet fully support all LINQ Operators either. It still supports more than WebApi though.
What about WebApi???
As of now (to my understanding), there is no "Data Context" support on Client (i.e. Silverlight, ASP.NET Server-Side Code, etc), because WebApi isn't really about Entity Data Models like WCF Data Services/OData is. It can expose Collections of Model Objects using IQueryable/IEnumerable, but there are no Primary Key/Foreign Key "Navigation Properties" (i.e. customer.Invoices) to use once the Entities are loaded on the Client, because there is no "Data Context" which loads them asynchronously (or in one call using $expand), and manages the changes. You have no code-generated "representation" of your Entity Data Model on the Client, like you do in RIA Services or WCF Data Services. I'm not saying you can't/don't have Models in the Client that represent your Data, but you have manually populate the Data and manage which "invoices" are to be set with each "customer" once they are retrieved over the Web. This can get tricky, specially with all the Async stuff going on. You don't know which calls will come back first. This may be hard to explain here, but just read about the "Data Context" stuff in RIA Services or WCF Data Services. So when dealing with Line of Business Apps, this is major issue for me. This is mainly based on productivity and maintainability. You can obsolulately build Apps without a Data Context. It just makes things easier, specially in Silverlight, WPF, and now Windows 8 Metro. Having relational Entities loaded into memory asynchronously and having Two-Binding is really nice to have.
Having said that, does this mean some day WebApi can support a "Data Context" on the Client? I think it could. Also, with more tooling, a Visual Studio Project could generate all your CRUD Methods based on a Database Schema (or Entity Framework).
Also, I know I'm only mentioning .NET to .NET Frameworks when it comes to working with WCF Data Services or WebApi, but I'm very aware that HTML/JS is also a major player. I was just mentioning the benefits I've found when dealing with a Silverlight UI, or ASP.NET Server-Side Code, etc. I believe with the advent of "IndexedDB" in HTML5/JavaScript that having a "Data Context" and a LINQ framework in JavaScript could also become available, making the ability of querying OData Services even easier from JavaScript (you can use DataJS today with OData). Plus, using KnockoutJS to support MVVM and Binding in HTML/JS as well, will make it a breeze :)
I'm currently researching which platform to use. I'd be happy using either, but I tend to lean towards OData based on the fact that my next Application is primarly about Analytics (read-only) and I want a rich expressive RESTful Api. I believe OData + WCF Data Services gives me that because WebApi only supports $take, $skip, $filter, $orderby over Collections. It does NOT support Projections, Includes ($expand), etc. I don't have a lot of "Updates/Deletes/Inserts" and our Data is fairly relational.
I hope others will join in the discussion and give their thoughts. I'm still deciding and would love to hear other opinions. I really think both are frameworks are great. I wonder if you have to even choose, why not use both if needed. From the Client it's all about building REST calls anyways. Just a thought :)