ActiveResource 本质上存在缺陷吗?

19

许多来自不同团队的开发人员独立告诉我,ActiveResource 是一个有缺陷的想法。最常见的批评是将其设计为具有类似 ActiveRecord 的接口是错误的。我还听到了一些关于错误处理方式的抱怨 - 或者说被忽略了。其中一个开发人员甚至创建了自己的 gem 来提供与 ActiveResource 相同的功能(基于 RESTful 资源的模型框架)。

对于 ActiveResource 我还很陌生,但是当我查看代码并进行实验并看到它如何工作时,我很难看出抵制它的根源。它似乎基于简洁、稳定的概念。我甚至听说过它太重了!但是在我的研究中,我发现它轻巧而且快速。

因此,在所有这些关于 ActiveResource 的争议中,我转向网络寻找答案。肯定有大量关于为什么应该放弃 ActiveResource 支持 X 的博客文章。毕竟,我肯定可以找到关于 DataMapper 是否优于 ActiveRecord 的文章。所以我搜索了,又搜索了......什么都没有。互联网上没有一个页面对 ActiveResource 提出任何批评(除了对 REST 的普遍批评)。我甚至找不到提出的替代方案。它得到了 Rails 核心团队的支持,似乎是社区中事实上的标准。

底线:

关于 ActiveResource 是否存在争议?如果有,争论的性质是什么?有没有替代方案?


4
你似乎比我更了解批评背后的智囊团。但我并不认为这是一个好的Stack Overflow问题。 - Dave Newton
3
如果不是在这里,它应该在哪里呢? - Eben Geer
也许可以在程序员聚集的地方或其他类似场合进行讨论,而不是只在争论中徘徊。请注意“无建设性”的关闭文本。另一个选择是实际包含争论的负面方面 - 如果除了你以外没有人听说过它,即使它确实与主题相关,任何人都很难去解决它。 - Dave Newton
2
你可能想要查看Yehuda Katz在今年的RailsConf上的演讲 - 关于表现层和Ember.js,那里提出了一些问题。 - timpone
9
实际上,它在Rails 4.0中已被移除。主要问题是,与SQL数据库不同,Rails后端非常不一致(我在演讲中提供了一些例子),因此ActiveRecord中的好的传统解决方案对ActiveResource并不奏效。我并不反对ARes的概念,但我们需要更好的约定来使其真正发挥作用。 - Yehuda Katz
显示剩余6条评论
2个回答

11

自2007年以来,我一直在使用ActiveResource,并建立和维护了一个多服务分布式架构,使用ARes从Rails v1.2到v4.0的过程中。在我看来,ARes在其当前形式下作为一个公共库是基本有缺陷的,但它包含了很多好的想法,可以在个人系统中使用。我曾经发表演讲,介绍我们公司如何迁移离开ARes。

人们不喜欢使用 ARes 的一个重要原因是由于维护不良或实现细节上的分歧。例如,你的同事提到的错误信息处理就属于这一类。此外,随着时间的推移,由于不明智的一次性改进或错误修复,甚至是 Rails 内部更改(例如去年 YAML-pocalypse 发生时),你会发现一些意外破坏了 ARes 系统。但所有这些问题都可以通过更好的维护和更好的愿景来改善,重要的是将这些问题与 根本 问题分开。

我所相信的,并且 Yehuda 在他上面的评论中所暗示的,是 ARes 失败是因为 REST API 没有一般具体的语义。即使利用最好的 Rails 约定,HTTP API 语义也是脆弱的。

与ActiveRecord不同的是,它生成SQL:一种用于选择数据行的明确定义的声明性语言。 SQL基于关系模型,根据不同子句给出了查询含义的数学定义。 这种数学基础是使得Arel可以在Ruby中创建可组合的SQL DSL的原因。在SQL数据库中,任何语法正确的查询都可以被执行(即使它太慢而无法实际使用),因为引擎被设计为正式解析和映射SQL语句以证明正确地实现操作和提取底层数据。因此,当您在其上构建像ActiveRecord这样的ORM时,您拥有底层系统的非常强大的保证。如果您生成有效的SQL,则引擎保证它将工作;如果您生成无效的SQL,则引擎将返回错误。即使使用了标准化的SQL,值得注意的是,每个数据库都有一个单独的ActiveRecord适配器,以确保正确性和正确映射到ActiveRecord功能。每个适配器都使用底层驱动程序来保证向正在运行的数据库正确实现线协议。所有这些代码都有相当多的规范和维护,所有这些都使今天的ActiveRecord具有良好的优雅和可靠性。
现在考虑一个HTTP API及其后端。它可以是任何数据库技术,也可能没有!它很可能是内部编写的,并仅提供业务功能所需的内容。与数据库不同,数据库模式中包含了有关通用查询操作的所有必要信息,而HTTP API完全与底层存储机制或业务逻辑解耦。即使API提供了如何使用查询参数的标准,也没有自我记录哪些过滤器或排序选项可用的定义。甚至检查参数的有效性也不能保证,因为API通常会吞下或忽略无效的参数。
话虽如此,ARes非常方便,但它建立在流沙之上。它使用的想法和约定很方便,但它们缺乏一个统一的愿景和稳定性来保证可靠性。个人认为,使用自己的约定和可靠规范构建类似于ARes的服务实现并不是不合理的。

就构建一个基础设施来支持像 ARes 这样的东西而言,Yehuda Katz 和 Steve Klabnik 的出色的 JSON:API 规范是一个伟大的社区项目,将为这样一个基础设施提供一个非常重要的构建块。然而值得注意的是,它仍然无法与特定的数据库驱动程序相比,具有语义保证和可推导功能。我怀疑一个真正好的利用 JSON-API 的类 ARes 库将会在很大程度上不同于今天的形式,以更好地拥抱与 RDBMS 相比隐含的灰色领域。

编辑:JSON:API 经过两年的激烈辩论和来自不同社区的反馈,刚刚发布了 1.0 版本。我估计这个规范所做的工作量比 ActiveResource 做的多几个数量级。虽然它与 ActiveResource 不同的抽象层次,但 JSON:API 追求的目标类似,即提供标准语义,使 API 更易于生成和消费。查看一些 implementations 可以很好地了解 JSON:API 可以提供多少杠杆效应。


1
你有没有考虑将你的ARes替代库以某种开源许可证发布出来?它看起来是非常整洁的代码,我最近开始开发一个API客户端应用程序,使用ARes映射到远程AR模型,我很想尝试一下。 - Galmi
我在演讲中展示的代码很可能会在某个时候成为开源代码(作为一个通用的MUBI客户端gem,当我们发布一个开放API时)。问题是,它还没有准备好作为通用的gem发布,因为我们只是为自己解决了一个非常狭窄的问题,一旦我们试图将其推广到所有API,功能请求就会涌现出来,而我们没有足够的带宽来支持这样一个规模相当大的公共项目,如果它得到任何严肃的采用。 - gtd

2

在Rails 4.0中,ActiveResource已经从Rails中移除。

许多人使用RestClient、HTTParty或其他库。这些库通常被认为更简单、更易于使用。


6
RestClient和HTTParty不能替代ActiveResource的功能。 - Eben Geer
2
ActiveResource比标准的RestClient或HTTParty提供了更多功能。JSON自动解码并表示为对象。它可以与Rails I18n本地化开箱即用。它还保留了一个类似于ActiveRecord / ActiveModel的错误哈希,因此可以轻松在flash中呈现。因此,与仅使用普通rest客户端相比,AR可以提供更多的功能。这取决于您的需求。 - Nicholas C
@EbenGeer,ActiveResource通常具有更多的功能和约定,但您可以使用所有三个库来实现相同的目的,或多或少。 - Scott Schulthess

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接