Wrest, REST and Ruby HTTP libraries

I've been using Rails' ActiveResource for over eighteen months to consume the POX based pseudo REST that Rails applications make so easy to produce, and I'm not overwhelmed.

ActiveResource isn't a particularly well written library, nor is it easy to extend, modify and use. It doesn't support certain features that I've come to consider essential for a Rails POX/REST client, like pagination. The only nice things you can say about it are that it works for the most common cases, and that it ships with Rails. But you know what hackers say about sucky tools - 'Don't get mad; roll your own'. So I did.

I started working on Wrest a few months ago with the intention of creating a drop-in replacement for ActiveResource. The section of the Wrest README that talks about Wrest::Resource is actually a record of the features that we've discussed over the dining table that we wished ActiveResource had. However, as I hacked away on Wrest, I slowly came to realise that a good REST client needs to be a good HTTP client first.

I took a look at those that were popular at the time, but they didn't really appeal to my engineering aesthetic. They heavily favoured class/static methods and seemed to be geared toward command line usage rather than as a library. So I started to implement a clean, easy to use and well encapsulated HTTP library first, resulting in Wrest::Core; it is now ready for use and is sufficiently mature that I'm comfortable writing about it and inviting people to take it for a spin. It does need a few more features, but nothing that can't be added with a few hours worth of hacking. Wrest::Resource however, is still a work in progress, but some of its building blocks are already ready for use. You can see some examples here.

Wrest is available for installation through both RubyGems and as a Rails plugin via Git.

To get the gem, all you need to do is (sudo) gem install wrest. If you want it as a Rails plugin, simply do script/plugin install git://github.com/kaiwren/wrest.git.

Wrest runs on Ruby 1.8, 1.9 as well as JRuby.

Here is an example that shows how you can use the Delicious API using Wrest. If you can't see it (it's a github gist that needs js) you can see the original source here. You may also be interested in the Twitter example, which showcases a more complex scenario with ideas and features from Wrest::Resource.

11 comments:

Anonymous said...

Why enforce .deserialize on every call?

Sidu said...

Wrest::Core is a 'library for a library' if you get my drift.

As such, I may not want to deserialise a response automatically (or at all) - hence the explicit call to deserialise.

Shantanu Kumar said...

You might find this relevant: http://github.com/caelum/restfulie

Hélião said...

Great library Sidu! I'm working on a project that will rely a lot on REST. I was trying to decide if I'd go with PHP or Ruby. When I saw this code I've made up my mind. I've always thought Ruby was a great language but, since I'd never had sponsorship at work, I was being lazy in catching up with it. Now that I'm in a project that the decision over the platform is up to me, I'm definitely going with ruby, thanks to you! Your code really inspired me. I was looking at the delicious example and thinking:

"Hey, how this string is suddenly making rest calls, that's making no sen... wait a minute. Gosh, this is great!" :)

Keep up the good work!

Sidu said...

@Shantanu Yeah, I know - that library's based off Jim Webber's book.

@Hélião Thank you! Your comment has given me considerable motivation to continue working on Wrest. Thanks again :)

Shantanu Kumar said...

@Sidu Could you give me an Amazon link for the book? Is it called "Get /Connected" by any chance? I saw his talk with same title on InfoQ sometime ago though.

Sidu said...

@Shantnu The book isn't published yet; it came up because we were talking about Restfulie on ThoughtWorks' internal dev mailing list and Jim mentioned he'd been collaborating with the guys from Caelum.

Guilherme Silveira said...

Hello Shantanu!

Do you have any tips that you can give us to improve restfulie?

Regards

Shantanu Kumar said...

@Guilherme

1. Restfulie is indeed very neat. I would wish for the "followup-metadata handling" part to be factored out into an independent small library so that other frameworks can readily use it. Ditto for the restfulie-java port. Shameless plug: http://code.google.com/p/bitumenframework/

2. An effective way to implement versioning is to mark it in the media-type of request payload. At some point of time, you may like to consider putting request payload-version / media-type in the followup metadata as well.

3. When users A and B have different permissions on a resource R, the metadata should report different followup links for A and B respectively. Doesn't it break HTTP caching (at least for the intermediary HTTP-aware routers)?

4. The followup metadata is a great way to expose permitted activities on a resource. Integrating this data with HTTP OPTIONS verb may introduce a more complete resource-store description. WADL Sucks!

These are just few of my thoughts and ideas. Please feel free to point out if my understanding about Restfulie appears to be incorrect, or if you have any questions -- kumar(dot)shantanu(at)gmail

Bradly Feeley said...

Hi Sidu,

Thanks for the library. It has made working with the Facebook API tolerable. One question though... Is it posible to do multipart posts for Facebook photo uploads as defined here http://wiki.developers.facebook.com/index.php/Photos.upload ? Thanks for any pointers!

-Brad

Sidu said...

In a word, yes. Give me a day or two and I'll have it set up for you.