c# - 带有 ServiceStack 的 OData?

标签 c# servicestack odata

<分区>

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

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

最佳答案

编辑

ServiceStack 现在添加了 Auto Query这是我们启用数据驱动服务的方法,可避免 the pitfalls and anti-patterns promoted by OData .


Will ServiceStack support OData.

没有。

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

糟糕的开发实践

OData 不适合 ServiceStack vehemently opposes heavy abstractions和我们视为 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.

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

提倡不良的网络服务做法

OData 还促进了您暴露内部实现细节服务的反模式,将您的隐式服务契约与底层 RDBMS 表紧密耦合,使您对可缓存性、重构的控制有限或将来您的服务的版本能力。

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

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

WebApi 是最佳选择,通过返回 IQueryable<T> 隐式支持 oData界面。

仅用于 Microsoft 独有的技术

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

OData 很慢

OData itself has found to be slow (这与我们的核心目标背道而驰)并且缺乏对实现的控制使得难以干净地实现性能增强技术,例如缓存它。

具体例子

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

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.

更新

Netflix 刚刚 retired its OData catalog, effective on April 8, 2013 .

why we recommend using clean, well-defined untainted DTO's for defining any remote services with 上添加了新答案,这是使用 OData 不提倡的远程服务最佳实践。

关于原因的好文章 generic based APIs like OData are much more fragile, complex and harder to use than equivalent intent-based APIs .

关于c# - 带有 ServiceStack 的 OData?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9577938/

相关文章:

c# - 如何查找 OData edm 模型类型到 clr 类型的映射?

c# - 为什么在 SqlDataReader 关闭之前我不能使用 SqlConnection 实例?

dynamic - 在 C# 中获取动态类型的 ServiceStack.redis 客户端

json - 将带有子项的实体类型发布到(MVC Web Api)OData 服务

c# - SOAPAction 和服务栈

redis - 透明的 Redis Dal 与 serviceStack Redis

wcf - 在运行时更改使用基本身份验证的 OData/WCF 数据服务的连接字符串

c# - 适用于 MonoTouch、适用于 Android 和 WP7 的 Mono 的经过身份验证的 WCF 服务

c# - 使用 OpenGL 时,C++ 比 C# 有哪些优势

c# - 关于锁对象和子类的问题