| Path: | README |
| Last Update: | Wed Nov 14 22:49:44 -0500 2007 |
Relax is a simple library for creating REST consumers.
When used as a basis for writing REST consumer APIs, it provides a set of functionality common to all REST consumers, including:
This short tutorial will walk you through the basic steps of creating a simple Flickr API that supports a single call to search for photos by tags.
In the first step we‘re going to simply include Relax, and define the basis for our Service class.
require 'rubygems'
require 'relax'
module Flickr
class Service < Relax::Service
ENDPOINT = 'http://api.flickr.com/services/rest/'
def initialize
super(ENDPOINT)
end
end
end
Next we‘re going to define common Request and Response classes for use throughout our API. This gives us a single point to add any shared functionality. For Flickr, this means that each request will have a "method" parameter, and each response will have a "stat" attribute that will equal "ok" when the response comes back without any errors.
module Flickr
class Request < Relax::Request
parameter :method
end
class Response < Relax::Response
def successful?
root[:stat] == 'ok'
end
end
end
While we‘re at it, we‘re also going to add a new line to the constructor from our service to make sure that our Flickr API key gets passed along with each request as well.
module Flickr
class Service < Relax::Service
ENDPOINT = 'http://api.flickr.com/services/rest/'
def initialize(api_key)
super(ENDPOINT)
Request[:api_key] = api_key
end
end
end
When we call our Request class as we have here, we‘re basically setting up a value on our request that acts like a template. Each request we create now will have the api_key property prepopulated for us.
Next, we‘re going to need a basic Photo class to represent photos that Flickr returns to us.
module Flickr
class Photo < Response
parameter :id, :attribute => true, :type => :integer
parameter :title, :attribute => true
end
end
Here we‘re creating a Response class that extends our Flickr::Response, which has two parameters: "id" and "title." By setting the attribute option to true, we‘re telling Relax to look for an attribute by that name on the XML root instead of checking for an element by that name. The type options can be used to specify what type of data we‘re expecting the response to give us. The default type is string.
Now we arrive at the final piece of the puzzle: a service call module. To keep things contained, a Relax best practice is to create a module for each call on your service. The one we‘re creating here is the PhotoSearch module for the "flickr.photos.search" call on the Flickr API.
There are three main pieces to every service call module:
This module then gets included into the Service class, where the call method can be easily utilized.
module Flickr
module PhotoSearch
class PhotoSearchRequest < Flickr::Request
parameter :per_page
parameter :tags
def initialize(options = {})
super
@method = 'flickr.photos.search'
end
end
class PhotoSearchResponse < Flickr::Response
parameter :photos, :element => 'photos/photo', :collection => Photo
end
def search(options = {})
call(PhotoSearchRequest.new(options), PhotoSearchResponse)
end
def find_by_tag(tags, options = {})
search(options.merge(:tags => tags))
end
end
end
As you can see, we have our request (PhotoSearchRequest), response (PhotoSearchResponse), and call method (actually, two in this case: search and
find_by_tag). This will get included into our Flickr::Service class, and we
can use it by calling either of the call methods.
flickr = Flickr::Service.new(ENV['FLICKR_API_KEY'])
relax = flickr.find_by_tag('relax', :per_page => 10)
if relax.successful?
relax.photos.each do |photo|
puts "[#{photo.id}] #{photo.title}"
end
end
This will output the IDs and titles for the first 10 photos on Flickr that have the tag "relax."