31

我刚刚看到了ServiceStack,我正在考虑用它构建一个服务。

是否可以使用服务堆栈为 OData 提要提供服务,以便我能够公开 IQueryable 并从客户端查询它?

4

1 回答 1

84

编辑

ServiceStack 现在添加了Auto Query,这是我们启用数据驱动服务的方法,可以避免OData 提倡的陷阱和反模式


ServiceStack 会支持 OData。

不。

反正不是直接的。如果有人看到 OData 中的任何价值,他们可以自由地将必要的功能添加为可选插件- 但它永远不会内置到 ServiceStack 核心中。

不良的开发实践

OData 不适合 ServiceStack,后者强烈反对重抽象和“魔术行为”,我们将其视为以下示例

当你花哨的框架做一些神奇的事情来帮助你时,你节省的每一分钟都会花费你未来十分钟的调试时间。不值得。

我们不认为依赖黑盒 blob 的神奇行为能经受住时间的考验。从历史上看,每当我们使用它(例如ADO.NET DataSetsASP.NET Dynamic Data)时,我们很快就会遇到这些框架固有的不灵活限制,这些框架无法发展以支持新的开发人员实践、范式和他们不是为支持而设计的技术,导致很快被弃用,取而代之的是可以支持的新框架。这是一个我们不希望推广的重写周期。

促进不良的网络服务实践

OData 还提倡反模式,您可以在其中公开服务的内部实现细节,将您的隐式服务合同与底层 RDBMS 表紧密耦合,从而使您对未来服务的可缓存性、重构或版本能力进行有限控制。

这类似于处理您的数据库连接字符串,一旦您在生产中绑定了客户端,表的结构就会冻结,从而抑制发展现有数据库表的能力,因为它可能会破坏现有客户端。ServiceStack 的建议是将您的客户端绑定到定义明确的服务层,您可以自由地重构其实现。

总而言之,OData 确实提供了丰富的功能,但我个人不建议在您无法控制且可以同时部署客户端和服务器的 Intranet 之外使用它。

IQueryable<T>WebApi 是通过返回接口隐式支持 oData 的最佳选择。

仅用于 Microsoft 专有技术

Web/远程服务(尤其是 SOA)的主要好处之一是它为您希望公开的任何功能提供了与技术无关且可互操作的外观。尽管OData是一个开放标准,但该技术本身基本上只被 Microsoft 和.NET 相关计划采用。

OData 很慢

OData本身发现速度很慢(这与我们的核心目标背道而驰),并且缺乏对实现的控制使得难以干净地实现性能增强技术,例如对其进行缓存。

具体例子

我在评论中给出了一个具体的例子,说明为什么 oData 是一个坏主意,在 IQueryable is Tight Coupling帖子的末尾,我将在此重复以保存:

Web 服务接口的整个想法是向外界公开与技术无关的可互操作 API。

公开 IQueryable/OData 端点可以有效地将您的服务与无限期地使用 OData 相结合,因为您将无法确定现有客户端绑定到哪些“查询空间”,即您需要无限期冻结/支持哪些现有查询/表/视图/属性. 当在 API 的表面区域公开任何实现时,这是一个问题,因为它限制了您在其上添加自己的自定义逻辑的能力,例如授权、缓存、监控、速率限制等。而且因为 OData 真的很慢,你会很早就遇到性能/扩展问题。缺乏对端点的控制,意味着您正在有效地进行重写: https ://coldie.net/?tag=servicestack

让我们通过查看来自 Netflix 的 OData api 的现有查询来看看移除 oData 提供程序实现是多么可行:

http://odata.netflix.com/Catalog/Titles ?$filter=Type%20eq%20'Movie'%20and%20(Rating%20eq%20'G'%20or%20Rating%20eq%20'PG-13 ')

该服务现在有效地耦合到一个名为“Titles”的表/视图和一个名为“Type”的列。

如果您不使用 OData,它将如何自然编写:

http://api.netflix.com/movies?ratings=G,PG-13

现在,如果出于某种原因您需要替换现有服务的实现(例如,出现了更好的技术平台,它运行速度太慢,您需要将此数据集移动到 NoSQL/Full-TextIndexing 支持的 sln)需要多少努力是否需要将 OData impl(有效地绑定到 RDBMS 模式和 OData 二进制 impl)替换为下面更直观的 impl-agnostic 查询?这并非不可能,但由于为新技术实现 OData API 非常困难,因此重写 + 破坏现有客户端往往是首选选项。

让内部实现决定面向外部的 url 结构是在需要更改时破坏现有客户端的可靠方法。这就是为什么您应该在酷 URI 后面公开您的服务,即不会更改的逻辑永久 url(不受实现的阻碍),因为您通常不希望限制服务的技术选择。

如果您想在其上提供临时“探索性服务”,这可能是一个不错的选择,但我不希望在生产系统中绑定外部客户端。如果我只打算将它的使用限制在我的本地 Intranet 上,那么它比仅仅给出一个只读连接字符串有什么优势?这将允许其他人使用他们最喜欢的 Sql Explorer、报告或任何其他会说 SQL 的工具。

更新

Netflix 刚刚停用了其 OData 目录,自 2013 年 4 月 8 日起生效

添加了关于为什么我们建议使用干净、定义明确的无污染 DTO 来定义任何远程服务的新答案,这是使用 OData 无法推广的远程服务最佳实践。

关于为什么像 OData 这样的基于泛型的 API 比同等的基于意图的 API 更脆弱、更复杂和更难使用的好文章。

于 2012-03-06T06:41:44.633 回答