OData with ServiceStack? [closed]

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.

Leave a Comment