31

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?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Shaddix
  • 5,901
  • 8
  • 45
  • 86
  • 1
    I have no experience with ServiceStack, but I know WCF Data Services has full OData support, and ASP.NET Web API supports some of the the parameters if you return IQueryable. see http://msdn.microsoft.com/en-us/library/cc668788.aspx – James Manning Mar 06 '12 at 05:08
  • WebAPI is perfect, the only problem is that I won't have a client-code generated for me if I'm using it.. I'll take a closer look at WCF Data Services if they could help me. Thanks for comment! – Shaddix Mar 06 '12 at 05:29

1 Answers1

85

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.

mythz
  • 141,670
  • 29
  • 246
  • 390
  • 2
    All good points, but bear in mind for many "enterprise" solutions all the clients might be part of a tightly coupled distrubuted system, in which case OData may still be a viable approach. – Jack Ukleja Jun 22 '16 at 02:49
  • 14
    Actually I feel like this answer conflates the OData standard with it's _implementations_. The implemenations are what provide the magic and expose implemation details. OData itself does not say the data model needs to be from db schema, it just so happens many of the implementations support such a thing out of the box. – Jack Ukleja Jun 22 '16 at 02:53
  • 2
    As for "Only used in Microsoft only technologies", as of 2016 it seems OData _may_ be getting some traction as seen by its uptake by SAP, IBM, Oracle, SalesForce, TIBCO etc. (not that those names are necessarily associated with innovative technology adoptions!) – Jack Ukleja Jun 22 '16 at 03:01
  • 1
    AutoQuery does look very cool but it does not seem to support insert/update/delete which OData does – Jack Ukleja Jun 22 '16 at 03:23
  • AutoQuery also lacks some of the more complex features found in the OData standard, but this answer is actually wrong on some of the points "promotes bad practices" is an implementation design choice by the dev not the standard, it's not slow if done right, and it's definitely not only used in Microsoft stacks. the concrete example given here isn't like for like as the OData version is a dynamicall generated question to the model the SS implementation is a concretely handled one. – War Mar 15 '20 at 15:15
  • I think the biggest limitation of AutoQuery is not being able to mix AND and OR logic. You have to pick one or the other. Pretty much every project I have worked on recently has required things like multicolumn searches and header filters that are impossible to implement with AutoQuery and involve modifying the underlying query which ends up getting confusing for the front end devs as multiple endpoints start working differently to each other. I think it needs the ability to mix AND and OR conditions into the query – Guerrilla Dec 24 '20 at 22:38
  • Wow, Netflix need some better engineers, it's not the fault of the protocol that the developers chose to design and expose a hideous database schema through their API, the example API request with OData should have looked like this: `http://api.netflix.com/movies?$filter=ratings in ('G','PG-13')` this is nothing more than a reflection of a depressing experience. Even in 2012, those rookie mistakes should not have been made by experienced software engineers. Unfortunately this post has permeated through the metasphere – Chris Schaller Feb 12 '22 at 12:18