OData with ServiceStack? [closed]
I just saw ServiceStack and I am considering building a service with it.
Is it possible to serve OData feeds with service stack so that I'd be able to expose IQueryable and query it from the client?
Edit
ServiceStack has now added Auto Query which is our approach to enabling data-driven services that avoids the pitfalls and anti-patterns promoted by OData.
Will ServiceStack support OData.
No.
Not directly anyway. If anyone sees any value in OData they are free to add the necessary functionality as an optional Plugin - but it will never be built into the ServiceStack core.
Poor development practices
OData is a poor fit for ServiceStack who vehemently opposes heavy abstractions and "magic behavior" which we view as a classic example of:
Every minute you save when your fancy framework does magical things to help you out costs future-you ten minutes of debugging. Not worth it.
We don't think relying on magic behavior from black-box blobs ever lasts the test of time. Historically whenever we've used this (e.g. ADO.NET DataSets, ASP.NET Dynamic Data) we've quickly run into the inherent in-flexible limitations of these frameworks which are in-capable of evolving to support new developer practices, paradigms and technologies they weren't designed to support, resulting in being quickly deprecated in favor of newer frameworks that can. This is a re-write cycle we don't wish to promote.
Promotes bad web service practices
OData also promotes the anti-pattern where you're exposing internal implementation details of your service tightly coupling your implicit service contract to the underlying RDBMS tables giving you limited control over the cachability, re-factoring or version-ability of your services in future.
This is akin to handing your db connection string where as soon as you have clients in production binding to it, the structure of the tables become frozen inhibiting the ability to evolve your existing DB tables since it could potentially break existing clients. ServiceStack's recommendation is having your clients binded to a well defined service layer that you are free to re-factor the implementation of.
To summarize OData does indeed provide rich functionality but I personally don't recommend its use outside the intranet where you don't control and can deploy both Client and Server.
WebApi is the best option with implicit support for oData via returning the IQueryable<T>
interface.
Only used in Microsoft only technologies
One of the major benefits of web/remote services (and SOA in particular) is that it provides a technology-agnostic and interoperable facade over any functionality you wish to expose. Although OData is an open standard, the technology itself has essentially only been adopted by Microsoft and .NET related initiatives.
OData is slow
OData itself has found to be slow (which is contra to our core objectives) and the lack of control over the implementation makes it difficult to cleanly implement performance enhancing techniques like caching over it.
Concrete example
I've given a concrete example in the comments of why oData is a bad idea, at the end of the IQueryable is Tight Coupling post which I'll repeat here for preservation:
The whole idea of web service interfaces is to expose a technology-agnostic interoperable API to the outside world.
Exposing an IQueryable/OData endpoint effectively couples your services to using OData indefinitely as you wont be able to feasibly determine what 'query space' existing clients are binded to, i.e. what existing queries/tables/views/properties you need to freeze/support indefinitely. This is an issue when exposing any implementation at the surface area of your API, as it limits your ability to add your own custom logic on it, e.g. Authorization, Caching, Monitoring, Rate-Limiting, etc. And because OData is really slow, you'll hit performance/scaling problems with it early. The lack of control over the endpoint, means you're effectively heading for a rewrite: https://coldie.net/?tag=servicestack
Lets see how feasible is would be to move off an oData provider implementation by looking at an existing query from Netflix's OData api:
http://odata.netflix.com/Catalog/Titles?$filter=Type%20eq%20'Movie'%20and%20(Rating%20eq%20'G'%20or%20Rating%20eq%20'PG-13')
This service is effectively now coupled to a Table/View called 'Titles' with a column called 'Type'.
And how it would be naturally written if you weren't using OData:
http://api.netflix.com/movies?ratings=G,PG-13
Now if for whatever reason you need to replace the implementation of the existing service (e.g. a better technology platform has emerged, it runs too slow and you need to move this dataset over to a NoSQL/Full-TextIndexing-backed sln) how much effort would it take to replace the OData impl (which is effectively binded to an RDBMS schema and OData binary impl) to the more intuitive impl-agnostic query below? It's not impossible, but as it's prohibitively difficult to implement an OData API for a new technology, that rewriting + breaking existing clients would tend to be the preferred option.
Letting internal implementations dictate the external facing url structure is a sure way to break existing clients when things need to change. This is why you should expose your services behind Cool URIs, i.e. logical permanent urls (that are unimpeded by implementation) that do not change, as you generally don't want to limit the technology choices of your services.
It might be a good option if you want to deliver adhoc 'exploratory services' on it, but it's not something I'd ever want external clients binded to in a production system. And if I'm only going to limit its use to my local intranet what advantages does it have over just giving out a read-only connection string? which will allow others use with their favourite Sql Explorer, Reporting or any other tools that speaks SQL.
Update
Netflix has just retired its OData catalog, effective on April 8, 2013.
Added new answer on why we recommend using clean, well-defined untainted DTO's for defining any remote services with, which is a remote services best-practices that using OData doesn't promote.
Good article on why generic based APIs like OData are much more fragile, complex and harder to use than equivalent intent-based APIs.