Writing a REST Client in Ruby

 
Published on 2010-12-17 by John Collins.

Introduction

In this tutorial, I will show you how to built a simple REST client with Ruby. I will assume that you will already have Ruby or JRuby installed. The client will be invoked from the command line, however these techniques can be used from within an Ruby code, for example a Rails controller to enable your web application to make REST calls.

The script I will present here talks to the Twitter public API, and invokes the method that returns a JSON array of all of the latest trends on Twitter. Here is an example response:

{"trends":[
{"url":"http:\/\/search.twitter.com\/search?q=Music+Bank","name":"Music Bank"},
{"url":"http:\/\/search.twitter.com\/search?q=%23delicious","name":"#delicious"},
{"url":"http:\/\/search.twitter.com\/search?q=%23shinee","name":"#shinee"},
{"url":"http:\/\/search.twitter.com\/search?q=Seulong","name":"Seulong"},
{"url":"http:\/\/search.twitter.com\/search?q=Word+Lens","name":"Word Lens"},
{"url":"http:\/\/search.twitter.com\/search?q=Blake+Edwards","name":"Blake Edwards"},
{"url":"http:\/\/search.twitter.com\/search?q=Nagging","name":"Nagging"},
{"url":"http:\/\/search.twitter.com\/search?q=SPECIAL+STAGE","name":"SPECIAL STAGE"},
{"url":"http:\/\/search.twitter.com\/search?q=Kwanghee","name":"Kwanghee"}]
,"as_of":"Fri, 17 Dec 2010 09:59:50 +0000"}

This API call is nice to use for two reasons:

You can find out more about this API call here:

http://dev.twitter.com/doc/get/trends

Lets begin by installing the required libraries.

Installing rest-client

The rest-client library (or gem in Ruby terminology) is a fantastic REST library for Ruby. It is easy to use for simple applications like this one, but mature enough to handle more complex use cases such as handling HTTP multi-part. You can find out more about the gem here:

https://github.com/archiloque/rest-client

As the script presented here uses the rest-client gem, you will need to install it by using either of the following commands (dependant upon whether you are using Ruby or JRuby):

Ruby: gem install rest-client
JRuby: jruby --command gem install rest-client

rest-client may prompt you to install an SSL dependency gem while you are installing it, which you should install if you are planning to use SSL in your scripts (we won't need that here though).

The Script

This is the script in it's simplest form:

# TwitterTrends1.rb
require 'rubygems'
require 'rest_client'
 
url = 'http://api.twitter.com/1/trends.json'
 
response = RestClient.get(url)
 
puts response.body

As you can see, the first few lines load rubygems (always required when working with gems) and the rest-client gem. We then define the URL for the Twitter API call we want to make, use the RestClient.get method to perform a HTTP GET request on that URL, and finally print (puts) the body of the HTTP response from Twitter to standard output. Here is an example of running the script from command line using JRuby:

$ jruby TwitterTrends1.rb
{"trends":[{"url":"http:\/\/search.twitter.com\/search?q=Music+Bank","name":"Music Bank"},
{"url":"http:\/\/search.twitter.com\/search?q=%23shinee","name":"#shinee"},
{"url":"http:\/\/search.twitter.com\/search?q=%23delicious","name":"#delicious"},
{"url":"http:\/\/search.twitter.com\/search?q=Word+Lens","name":"Word Lens"},
{"url":"http:\/\/search.twitter.com\/search?q=Seulong","name":"Seulong"},
{"url":"http:\/\/search.twitter.com\/search?q=Blake+Edwards","name":"Blake Edwards"},
{"url":"http:\/\/search.twitter.com\/search?q=Kwanghee","name":"Kwanghee"},
{"url":"http:\/\/search.twitter.com\/search?q=Magic+Girl","name":"Magic Girl"},
{"url":"http:\/\/search.twitter.com\/search?q=SPECIAL+STAGE","name":"SPECIAL STAGE"}],
"as_of":"Fri, 17 Dec 2010 10:39:16 +0000"}

As you can see, we have a fully-functional REST client in 5 lines of Ruby code!

Improving the Script

The script above is perfect for showing you how easy it is to use rest-client, however it is not very usable in it's current states. Lets make a number of improvements:

Here is the improved script:

# TwitterTrends.rb
require 'rubygems'
require 'rest_client'
require 'json'
 
class TwitterTrends
    # the URL for the Twitter Trends endpoint
    @url
 
    # constructor
    def initialize
            @url = 'http://api.twitter.com/1/trends.json'
    end
 
    # performs the GET request to get the trends from Twitter
    def getTrends
            response = RestClient.get(@url)
            return response.body
    end
 
    # returns the raw JSON of the response from Twitter
    def getJSON
            return getTrends()
    end
 
    # returns a human-friendly text version of the response from Twitter
    def getText
            hashOfResponse = JSON.parse(getJSON())
            textOfResponse = "Twitter Trends\n----------------\n\n"
            textOfResponse += "Results for: "+hashOfResponse['as_of']+"\n\n"
            # loop over the trends URLs returned and append them to the string to return
            hashOfResponse['trends'].each { |trend|
                    textOfResponse += "Trend: "+trend['name']+", URL: "+trend['url']+"\n"
            }
            return textOfResponse
    end
end

Note that here I am using the json gem for Ruby (http://flori.github.com/json/) which you can install using:

Ruby: gem install json
JRuby: jruby --command gem install json

And now to use the above class to print out the human-friendly Twitter trends result:

# displayTwitterTrends.rb
require 'TwitterTrends'
 
client = TwitterTrends.new
puts client.getText()

And if I run this script, here are the results:

$ jruby displayTwitterTrends.rb
Twitter Trends
----------------

Results for: Fri, 17 Dec 2010 11:34:02 +0000

Trend: Femke Halsema, URL: http://search.twitter.com/search?q=Femke+Halsema
Trend: #somethingaintright, URL: http://search.twitter.com/search?q=%23somethingaintright
Trend: Music Bank, URL: http://search.twitter.com/search?q=Music+Bank
Trend: #sjbestofbest, URL: http://search.twitter.com/search?q=%23sjbestofbest
Trend: #shinee, URL: http://search.twitter.com/search?q=%23shinee
Trend: Word Lens, URL: http://search.twitter.com/search?q=Word+Lens
Trend: Roitfeld, URL: http://search.twitter.com/search?q=Roitfeld
Trend: Blake Edwards, URL: http://search.twitter.com/search?q=Blake+Edwards
Trend: Jolande Sap, URL: http://search.twitter.com/search?q=Jolande+Sap
Trend: Magic Girl, URL: http://search.twitter.com/search?q=Magic+Girl

Conclusion

Using the example code from the TwitterTrends.getText method, you could easily add other output formats, for example a TwitterTrends.getHTML method to return a HTML table of the latest Twitter trends. The rest-client gem is very powerful. I have been working with it for over a year now and have written scores of command line clients using it, like for example Ruby unit tests on REST API servers that were being built in parallel. The above example serves as just a tiny introduction to the versatility of this gem and the Ruby language itself.


Updated 2022 : note that the above post was originally published in 2010, but is left here for archival purposes. Most of the external links, including for the old Twitter Trends API, are now dead so I have unlinked them.