Wednesday, June 06, 2007

What is a RESTful application?

In the Rails community (and elsewhere) there is a lot of talk about "RESTful applications". But there is a lot of questions of what is really meant by REST. IMHO the most characteristic and interesting parts of REST is:

  • Everything is a resource, uniquely addressable using a URI.
  • There are a few well-defined operations to view and change state of a resource
For Rails, the REST-buzz started with David's keynote at RailsConf last year and the "RESTful" controllers/routing was part of Rails 1.2, where it is very easy to create a webapp with "RESTful" characteristics (the new routing etc.). The client side of the RESTful interface, Active Resource, was not part of rails 1.2 but now can be easily used anyway. I come back to how soon...

Maybe the easiest way to create a RESTful application in rails is using the "scaffold_resource" generator (since rails 1.2).

Example "service":
$ ./script/generate scaffold_resource result match_date:date home_team:string\
away_team:string home_score:integer away_score:integer
$ rake db:migrate
$ ./script/server

Apart from giving a web application that can be used right away this also gives a REST-service that can be used with for example curl. When at least one item has been added with the scaffold web app, it can look like the following.
$ curl http://localhost:3000/results/1.xml

<?xml version="1.0" encoding="UTF-8"?>
<result>
<away-score type="integer">0</away-score>
<away-team>Denmark</away-team>
<home-score type="integer">3</home-score>
<home-team>Sweden</home-team>
<id type="integer">1</id>
<match-date type="date">2007-06-02</match-date>
</result>


Ok, that's fine. There is a lot of stuff that we get for free when using scaffold_resource. But how can we have a little more sophisticated client than curl?
Here comes the fun part. As I said above, ActiveResource was not part of Rails 1.2, but we don't even need to run edge-rails to run it now. It has been released as a gem and can be easily downloaded and installed, see Ryan's post for more info.
  • sudo gem install activeresource --source http://gems.rubyonrails.org
If the activeresource gem is installed we only need a couple lines of ruby code to access and make changes to resources. We don't even need rails, a small ruby-client will do.

require 'rubygems' 
require 'active_resource'

class Result < ActiveResource::Base
self.site = "http://localhost:3000/"
end

result = Result.find(1)
p result.home_team



This will access my REST-service and print out the home team of the resource "results/1" => Sweden.

The really cool use of activeresource comes when I want to create a new record. When I add to my following code example:

Result.create :home_team=>"Sweden", :away_team=>"Iceland", :home_score=>5, :away_score=>0, :match_date=>Time.now


It creates a new entry in my railsapp, that instantly can be accessed by activeresource or in a browser with
http://localhost:3000/results/2

I think it is pretty amazing that you in just a few lines of ruby code can create both a REST-service and client. The next step for me will be to test how activeresource and REST might work for a larger application. How about error handling? Using other clients than Ruby towards my REST-service (like a Java-client)? Can I throw out my SOAP-solutions now? (say yes!)...

No comments: