Implementing only certain aspects of OData

While we focus on keeping things simple, the whole OData protocol does have a bunch of functionality in it, and you don’t always need the whole thing. If you’re implementing a client or a server, how much of OData do you need to handle?


OData is designed to be modular and grow as you need more features. We don’t want to dictate exactly everything a service needs to do. Instead we want to make sure that if you choose to do something, you do it in a well-known way so everybody else can rely on that.


Here is one possible way of slicing the capabilities of the protocol into various click-stops. I’m sure there are others as well.



You can use OData just as a way of representing a bunch of rows, typically available on an HTTP end point and retrievable using HTTP GET (although a file on disk will do just as well if you let go of content type negotiation and such).  


A set of rows in OData is represented using an Atom feed, where each entry has the usual metadata plus structured data encoded as name/value pairs inside content. For example, check out the content of this feed (if you’re using a browser that automatically renders Atom feeds in a nice view, you may want to turn that off):


A couple of incremental things you can add:

– Type annotations to individual properties to have full type fidelity (visible in the example above)

– You can use Atom-style paging (e.g. a link with a rel of “next”) for server-driven paging of large rowsets


What do you get? A server supporting this has enough, for example, for PowerPivot ( to load data from it. The Data Services clients will also work if you hand-craft a type that matches the shape of the data (or the subset of the shape you care about).



You can choose to support simple query options such as filter ($filter), sorting ($orderby), paging ($top, $skip), projections ($select) and inline expansion ($expand). For example:$filter=zipcode eq 20007


(this service endpoint only supports filter and paging, no sorting and no projections for now)


The actual definitions of all these options is documented in if you want to look at it in more detail.


What do you get? Developers using the Data Services client for .NET would be able to use LINQ against your service, at least for the operators that map to the query options you implemented.


Service Documents

You can choose to add a service document to collect links to multiple collections that make up a data set, for example:


What do you get? With this clients can discover what collections of data your service exposes. Some clients such as PowerPivot will use this to let the user browse data sets.



You can choose to add rich metadata describing the collections, shapes of resources in each collections, and their associations through the Entity Data Model. For example (not the best example as it does not contain associations):$metadata


What do you get? If you have metadata then Visual Studio can automatically generate .NET classes for your service types, and a service entry point with properties for each of your top-level sets. The OData visualizer also can allow developers to view and understand the structure of your data service.



You can choose to support updates through HTTP POST/PUT/DELETE verbs. Most services that allow updates don’t allow anonymous access so I can’t easily share an example, but it would be POSTing or PUTing the same payload you GET. For DELETE only the URL is needed. For all update operations you can use ETags for optimistic concurrency control if that’s required for your scenarios.


What you get? Clients that support updates such as the .NET, AJAX, Silverlight, PHP and Java ones would be able to submit changes to the server.



While we encourage folks to support for Atom and JSON formats, you can get pretty far with Atom alone.



More sophisticated features in OData include batching and changesets for round-trip optimization and unit-of-work support.


What you get? Clients that support batching (most of them do) would get not only optimizations for multiple queries, but the ability to save a whole unit of work (a set of changes that are applied atomically).



Data Services uses Atom’s “media link entries” to manage large blobs such as media elements. Clients and servers will handle media if you expose them following the Atom way.



The details required for each of the areas here are discussed in the OData specs which are accessible at


[Update 1/28/10] I got this question several times so it’ll clarify here: these are not “incremental levels”. Implementing the “rows” category is kind of fundamental, but other than that you can pick and choose what to implement based on the capabilities of your back-end system, what clients you want to enable and the requirements of your particular scenario.




Comments (0)