Relax

Relax is a library that provides a foundation for writing REST consumer APIs, including the logic to handle the HTTP requests, build URLs with query parameters, and parse responses.

Tutorial

This short tutorial will walk you through the basic steps of creating a simple Flickr API consumer that supports a single call to search for photos by tags.

First Things First

The first step we’ll take is to load the Relax gem.

require 'rubygems'

gem 'relax', '~> 0.1.0'
require 'relax'

Then we’ll define our service class.

class Flickr < Relax::Service
end

Adding an Endpoint

An endpoint is the base URL for the service we’ll be consuming. All of our actions will be nested inside of an endpoint and build on top of it to forumlate the final request URL.

class Flickr < Relax::Service
  endpoint 'http://api.flickr.com/services/rest/' do
  end
end

Adding Default Parameters

Since Flickr requires us to always pass an API key parameter let’s make that a

required default parameter in our service class.

 class Flickr < Relax::Service
   defaults do
     parameter :api_key, :required => true
   end

   endpoint 'http://api.flickr.com/services/rest/' do
   end
 end

Adding an Action

So we have our service now, but we need to define an action before we can actually fetch any data from it.

class Flickr < Relax::Service
  defaults do
    parameter :api_key, :required => true
  end

  endpoint 'http://api.flickr.com/services/rest/' do
    action :search do
      parameter :method, :default => 'flickr.photos.search'
      parameter :per_page, :default => 5
      parameter :tags
    end
  end
end

We’re defining an action here called :search that will create an instance method on our service with the same name. There are three parameters, :method, :per_page, and :tags, with :method and :per_page receiving default values.

There are lots of other parameters for the flickr.photos.search method that we could define, but we’ll just stick with these for simplicities sake.

A Small Refactoring

When adding more methods it will quickly become obvious that we have another common parameter in :method. We can refactor our service class slightly to make this a default parameter for all of the actions on our endpoint.

class Flickr < Relax::Service
  defaults do
    parameter :api_key, :required => true
  end

  endpoint 'http://api.flickr.com/services/rest/' do
    defaults do
      parameter :method, :required => true
    end

    action :search do
      set :method, 'flickr.photos.search'
      parameter :per_page, :default => 5
      parameter :tags
    end
  end
end

The set method allows us to define a default value for a default parameter so we don’t have to redefine common parameters inside every action.

Defining a Parser

Before we can actually perform a request we need to let the service know how to handle the response. This is done by defining a parser.

class Flickr < Relax::Service
  defaults do
    parameter :api_key, :required => true
  end

  endpoint 'http://api.flickr.com/services/rest/' do
    defaults do
      parameter :method, :required => true
    end

    action :search do
      set :method, 'flickr.photos.search'
      parameter :per_page, :default => 5
      parameter :tags

      parser :rsp do
        attribute :stat, :as => :status

        element :photos do
          attribute :page
          attribute :pages
          attribute :perpage, :as => :per_page
          attribute :total

          elements :photo do
            attribute :id
            attribute :owner
            attribute :secret
            attribute :server
            attribute :farm
            attribute :title
            attribute :ispublic, :as => :is_public
            attribute :isfriend, :as => :is_friend
            attribute :isfamily, :as => :is_family
          end
        end
      end
    end
  end
end

dhe parsing is performed by the Relief gem, so you can find out more about the syntax in its own documentation.

Making a Call

Now, we’re able to create a new instance of our service with the API key set.

flickr = Flickr.new(:api_key => FLICKR_API_KEY)

We can now use this object to search for photos by tag.

flickr.search(:tags => 'cucumbers,lemons')

This will return a Ruby response hash.

{
  :status => "ok",
  :photos => {
    :page => "1",
    :pages => "3947",
    :per_page => "5",
    :total => "19733",
    :photo => [
      { :is_public => "1", :secret => "3c196485d2", :server => "3182", :is_friend => "0", :farm => "4", :title => "lemons", :is_family => "0", :id => "3509955709", :owner => "37013676@N06" },
      { :is_public => "1", :secret => "44f1306a63", :server => "3326", :is_friend => "0", :farm => "4", :title => "Peeto", :is_family => "0", :id => "3509461859", :owner => "13217824@N04" },
      { :is_public => "1", :secret => "dce53bce7f", :server => "3364", :is_friend => "0", :farm => "4", :title => "Peeto Above", :is_family => "0", :id => "3509459585", :owner => "13217824@N04" },
      { :is_public => "1", :secret => "12f9ba167c", :server => "3632", :is_friend => "0", :farm => "4", :title => "Lemonaid", :is_family => "0", :id => "3509415752", :owner => "35666391@N03" },
      { :is_public => "1", :secret => "8caac1ff46", :server => "3320", :is_friend => "0", :farm => "4", :title => "Gardening 365 (Day 8)", :is_family => "0", :id => "3509251322", :owner => "21778017@N06" }
    ]
  }
}

Copyright © 2007-2009 Tyler Hunt. See LICENSE for details.