Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is ActiveResource fundamentally flawed?

Several developers from different teams have independently told me that ActiveResource was a flawed idea. The most common criticism I hear is that it was a mistake to design it to have an ActiveRecord-like interface. I also hear complaints about the way errors are handled - or swallowed. One developer actually created his own gem to provide the same functionality as ActiveResource (a framework for models based on RESTful resources).

I am new to ActiveResource, but when I look at the code and experiment and see how it works, I struggle to see where the resistance is coming from. It seems to based in clean, solid concepts. I've even heard it's too heavy! But in my examination, I find it light and fast.

So with all this controversy about ActiveResource, I turned to the Web for answers. Surely, there must be stacks of blog posts about why ActiveResource should be canned in favor of X. After all, I can sure find posts about whether DataMapper is superior to ActiveRecord. So I've searched and I've searched and ... nothing. Not a single thing. I can't find a single page on the Internet making any criticism of ActiveResource (aside from blanket criticism of REST). I can't even find a proposed alternative. It has the support of the Rails core team and it seems to be the de facto standard in the community.

Bottom line:

Is there a controversy about ActiveResource? And if so, what is the nature of the debate? Are there alternatives?

like image 280
Eben Geer Avatar asked May 28 '12 23:05

Eben Geer


2 Answers

I have worked with ActiveResource extensively since 2007 and have built and maintained a multi-service distributed architecture using ARes over the period when Rails went from v1.2 to v4.0. In my opinion ARes is fundamentally flawed as a public library in its current form, but it contains a lot of good ideas which can be put to use within individual systems. I gave a talk about what we did at my company to migrate away from ARes.

A big reason people don't like ARes in practice are because of poor maintenance or implementation details they disagree with. Things like the error message handling your colleague mentioned fall under this category. Also, over time you'll find things breaking unexpectedly due to ill-advised one-off improvements or bug fixes, or even Rails internal changes percolating up (eg. when the YAML-pocalypse hit last year, we suffered catastrophic breakdown in our ARes systems). But all of these things can be improved with better maintenance and better vision, it's important to separate these issues from the fundamental issue.

What I've come to believe, and what Yehuda alludes to in his comment above, is that ARes fails because REST APIs have no general concrete semantics. Even leveraging the best of Rails conventions, HTTP API semantics are flimsy at best.

Contrast this to what ActiveRecord does, it generates SQL: a well-defined declarative language for selecting rows of data. SQL is based on the relational model which gives us mathematical definitions of what a query means based on different clauses. This mathematical underpinning is what allows something like Arel to create a composable SQL DSL in ruby. In a SQL database, any syntactically correct query can be executed (even if it's too slow to be practical) because the engine is designed to formally parse and map SQL statements to provably correct implementation that manipulates and fetches the underlying data. So when you build an ORM like ActiveRecord on top of this, you have very strong guarantees in the underlying system. If you generate valid SQL the engine guarantees it will work, if you generate invalid SQL the engine returns you an error. And even with the standardization of SQL, it's worth noting that every database has a separate ActiveRecord adapter to ensure correctness and proper mapping to ActiveRecord features. Each of these uses an underlying driver to guarantee correct wire protocol implementation to the running database. All of this code has quite a large amount of specification and maintenance behind it, all of which enables the benign elegance and reliability of today's ActiveRecord.

Now consider an HTTP API and its backing? It could be any database technology under the sun or none at all! It's most likely written in-house and serves up only what is necessary for the business function. Unlike a database which carries in its schema all the necessary information about the operation of generic queries, an HTTP API is completely decoupled from any underlying storage mechanism or business logic. Even if an API provides a standard for how it uses query params, there's no self-documenting definition of which filter or sorting options are available. Heck, even checking the validity of params is not guaranteed, as often as not an API will just swallow up or ignore an invalid param.

All that said, ARes is very convenient, but it's built on quicksand. The ideas and conventions it uses are handy, but they lack a cohesive vision and stability to be reliable. Personally I think rolling your ARes look-alike with its own conventions and solid specs which you can then apply to your service implementation is not unreasonable.

In terms of building a foundation on top of which something like ARes could make sense, Yehuda Katz and Steve Klabnik's excellent JSON:API specification is a great community project that will provide one very important building block of such a foundation, however it's worth noting that it still doesn't come anywhere near a specific database driver in terms of semantic guarantees and derivable functionality. I suspect that a really good ARes-like library to leverage JSON-API will look significantly different from what it does today to better embrace the gray areas implicit in an adhoc API compared to a RDBMS.

Edit: JSON:API has just hit 1.0 after a very intense two years of debate and feedback from diverse communities. I would estimate the amount of work put into this spec is a couple orders of magnitude more than ActiveResource ever achieved. Although it's a different abstraction level from ActiveResource, JSON:API pursues a similar goal of providing standard semantics so that APIs are easier to produce and consume. Looking at some of the implementations gives a good idea of how much leverage JSON:API can provide.

like image 54
gtd Avatar answered Oct 18 '22 16:10

gtd


ActiveResource has been pulled from Rails in Rails 4.0.

A lot of people just use RestClient or HTTParty or another library. Those libraries are generally regarded as simpler and easier to use.

like image 40
Scott Schulthess Avatar answered Oct 18 '22 16:10

Scott Schulthess