The Open Data Protocol
Software Development March 25th, 2010I recently went to the MIX developer’s conference in Las Vegas, and one of the topics that I put on my list of things to get more familiar with is the Open Data Protocol, or OData for short. To put it simply, OData is an HTTP based method for sharing data. I highly recommend checking out the OData site to get more familiar with the protocol from a technical standpoint. To sum it up, I’ll just say that it’s built on conventions used in the Atom Publishing Protocol. (AtomPub)
There are several public OData feeds already available, but the one I used to get my feet wet was the Netflix OData Catalog API. This was part of the day 2 keynote at the MIX conference, and it seemed like a good feed to learn the ropes with. There are a lot of different ways you can query the feed, (you can even use a browser) but I felt the best way to get started was to use LINQPad. I recommend installing the .NET Framework 4.0 RC and installing the corresponding version of LINQPad, it worked better with the Netflix OData feed when I was learning it.
LINQPad supports WCF Data Services out of the box, so you will be literally be querying the Netflix feed in minutes. All you have to do is start the program and click the Add Connection link on the top left. You will be presented with a dialog box like this one:
Select WCF Data Services from the list and hit the next button. You will then be presented with this dialog:
All you have to do here is type in the URL of the feed, which is this case is http://odata.netflix.com/Catalog. After you hit the OK button you are ready to start writing queries, it really is that easy. Once you have your feed set up, LINQPad figures out what information that the feed is providing and outlines it for you on the left side.
At this point you can start writing queries in LINQ. Here are a few sample queries that I came up with:
What if I wanted to get a list of all of the awards that Al Pacino has won?
from p in People.Expand("Awards") where p.Name.Equals("Al Pacino")
If you run that query in LINQPad, you get the following results:
I used the Expand method to expand the Awards collection off of the Netflix defined People section. This is a method available off of the DataServiceQuery<T> class, which is how the results come back. This result isn’t quite as useful as I’d hoped since I still need to expand the CatalogTitle to see which movie is associated with each award. This can be accomplished by chaining another Expand call, the only thing to notice is the ‘/’ rather than the ‘.’ that you might expect when accessing the collection:
from p in People.Expand("Awards").Expand("Awards/Title") where p.Name.Equals("Al Pacino") select p
This returns us the CatalogTitle information as well, so we can see that in 1993, Al Pacino won the Academy Award for Best Actor for his role in Scent of a Woman.
How about something a little more complex. I want to see all ‘R’ rated movies released in 2009 that are available in Blu-Ray with a netflix rating of 4 or higher. This is trivial with a simple LINQ expression:
from t in Titles where t.Type.Equals("Movie") && t.AverageRating >= 4 && t.BluRay.Available == true && t.ReleaseYear == 2009 && t.Rating.Equals("R") orderby t.AverageRating descending select new { t.Id, t.RegularTitle, t.Synopsis, t.ReleaseYear, t.Rating }
In the previous example, I also used an anonymous type to only show the data I was interested in, and I sorted the results based on their rating from highest to lowest. This query produced the following result:
It might be a little tough to see, but the query returned 4 movies that fit the criteria. Just to prove you can do the same thing straight from the browser, the same query as above could be run straight from the browser using this link. The only thing this link doesn’t do that my query above does is restrict the amount of data being brought back. To get a better idea of how to navigate an OData using URL’s check this article out.
Visual Studio 2010 provides OData support straight out of the box as well. I would also suggest adding the Open Data Protocol Visualizer plugin, which allows you to see a read-only graphical representation of the types and relationships provided in a WCF Data Service. I created a Service Reference to the Netflix OData feed to show you a sample of what this plugin can output.
I really like the direction that Microsoft is going with OData. This protocol will become more and more useful as more providers start creating feeds. This should allow developers to create mashups fairly easily and consume data that already exists in the public domain. Microsoft is really pushing the adoption of this protocol…I found this image over at Douglas Purdy’s blog which sums up OData support pretty well I think.
I want to show one more way that OData feeds can be consumed. I downloaded the Office 2010 Beta and then installed Power Pivot to check out the native OData integration that is available. I was able to quickly set up a connection to the Netflix feed, as shown here:
To add the feed, click the PowerPivot Window in the top left, then choose the From Data Feeds button from the pop-up that you get. When you choose "From Data Feeds” you will get a drop down, select “From Other Feeds” and you will be presented with the Data Feed Dialog above. All you have to do is enter the same URL as before and Power Pivot will discover the available elements from the feed as shown here:
You can import any of the sections from this screen, but keep in mind that if you try to import all of the catalog titles it is going to take a while! Just to show that Excel can grab this data, I entered the URL from our browser above rather than the base of the feed to import the same 4 records as in our previous example.
I really like the potential for this data protocol, and I’m really hoping it picks up steam. I hope this quick intro at least convinces a few people to check out OData. I should mention that producing OData is just as simple as consuming it. Sharepoint 2010 supports this out of the box, and you can see a great example of it from the screencast available here.
March 26th, 2010 at 9:25 am
In a fantastic display of good timing, it appears that the Netflix OData feed has changed. What are the odds that it would change the very next day after posting an article!!
I have updated the Linq queries so that they work correctly, but the result screenshots are not the same, since today the same query returns 2 results rather than 4, I’m guessing because the ratings have changed.
April 1st, 2010 at 12:37 am
I am trying to execute the following LINQ query (in both LINQPad and VS2008) and am getting an error
from p in People.Expand(“Awards”)
where p.Name.Equals(“Al Pacino”)
select p
System.Data.Services.Client.DataServiceQueryException was caught
Message=”An error occurred while processing this request.”
Source=”System.Data.Services.Client”
StackTrace:
at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServiceContext context, Uri requestUri)
at System.Data.Services.Client.DataServiceQuery`1.Execute()
at System.Data.Services.Client.DataServiceQuery`1.GetEnumerator()
at LinqToNetflix.Program.Test() in C:\Users\rbass\Documents\Visual Studio 2008\Projects\LinqToNetflix\Program.cs:line 38
at LinqToNetflix.Program.Main(String[] args) in C:\Users\rbass\Documents\Visual Studio 2008\Projects\LinqToNetflix\Program.cs:line 18
InnerException: System.Data.Services.Client.DataServiceClientException
Message=”\r\n\r\n
\r\n Request version ’1.0′ is too low for the response. The lowest supported version is ’2.0′.\r\n”
Source=”System.Data.Services.Client”
StatusCode=400
StackTrace:
at System.Data.Services.Client.QueryAsyncResult.Execute(MemoryStream requestContent)
at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServiceContext context, Uri requestUri)
InnerException:
April 1st, 2010 at 8:28 am
I think you need to install the 4.0 RC of the framework for the query to work, I think that’s what the message “Request version ’1.0′ is too low for the response” means.
There is a header sent called DataServiceVersion, and with previous versions of the framework it is being set to 1.0 instead of 2.0. You can confirm the value that you are sending using a tool like Fiddler.
October 28th, 2010 at 4:28 am
PC Support and Computer repairs and support…
PC Support and Computer repairs and support…