REST can be a big scary subject. However, the concepts behind it are relatively straight forward.

As most web programmers know HTTP is a stateless protocol, meaning there is no connection maintained between the web browser and the web server; you ask for a page, the server gives it to you. End of communication. What REST attempts to do is standardise a way of building meaning into the actual request from the browser.

HTTP has a 4 verbs that represent interactions with the server. The original purpose for these verbs were:

GET     =>  Get something
POST    =>  Create something new
PUT     =>  Update something
DELETE  =>  Delete something

When using data, these are the basic operations that we use. What we do in a RESTful application is use these verbs in conjunction with a resource style URL scheme.

For example, let's say we have a 'Person' object on our system. In Rails, we'll have a 'Person' model with a corresponding 'people' table. The RESTful URLs for interacting with our 'people' would look like this:

GET     /people/    =>  Get a list of all people
POST    /people/    =>  Create a new person with the submitted form data
GET     /people/1   =>  Get the person with the id of '1'
PUT     /people/1   =>  Update person '1' with the submitted form data
DELETE  /people/1   =>  Delete person '1'

As you can see, the structure of our URLs is simple and clear. In Rails there are additional GET actions to show 'new' and 'edit' forms:

GET /people/new     =>  Get the 'new person' form
GET /people/1/edit  =>  Get the edit for for person '1' *

(Note: Rails 1.2 uses a semi-colon to denote these additional actions e.g. /people/1;edit. This has since been altered in Edge Rails to use the standard foward-slash notation)

REST in Rails

As with most things in Rails this is very easy to set up. A simple declaration in your routes.rb file:

map.resources :people

This will automatically route the URLs above to the corresponding actions in your PeopleController. You'll also get a load of named routes:

people_url
new_person_url
person_url(1)
edit_person_url(1)

Adding a method attribute to these will give you the 'verb' style URLs:

people_url, :method => :post
person_url(1), :method => :delete

It's worth noting at this point that most browsers do not support all 4 verbs outlined - they tend to only use POST & GET. Rails gets around this by using hidden fields containing the correct verb. Thankfully, Rails manages this for us.

Nested Resources

So what if we our 'people' have many 'cars'? Once again, it's straight forward to set up:

map.resources :people do |person|
  person.resources :cars
end

This maps routes to a corresponding CarsController and gives us these URLs:

GET   /people/1/cars  => Get the cars for person '1'
POST  /people/1/cars  => Create a new car for person '1'
etc..

In CarsController, we can add a before_filter to pick up the person's id from the url

def find_person
  @person = Person.find(params[:person_id])
end

Conclusion

I didn't want to go into to too much detail here, but I hope I've outlined the basics of REST is all about and how you can use it in Rails to structure your application's interaction with the browser.

REST is surrounded by quite a bit of controversy as many developers believe that it is simplistic to try and define an entire application using only 4 verbs. However, I've found that using RESTful URLs covers 80-90% of the applications I write so it's a great place to start. If you find you need to add a richer set of interactions then you are free to do so.

At the end of the day, thinking in REST will give you a solid, convention-rich foundation to build on.

3 Responses to “What is REST in Rails and why should I care?”

  1. Adam Michela Says:
    Great write-up. Thanks.
  2. noodl Says:
    As pointed out, a well phrased writeup. I'd be interested to see a solution to the issue that's keeping me away from rails 'rest' though which is how to update multiple model objects in a single request, while keeping things restish.
  3. Stephen Bartholomew Says:

    noodl: I'm sure I'll get blasted for saying this, but I don't really see huge a problem with PUTing a collection against the /people/ URL.

    That's effectively what you're - updating the people collection.

    I'm sure there are plenty of opinions on this, but I generally find that it pays to work within the REST setup and bend the rules if you need to.

    It's all about 80/20...

Sorry, comments are closed for this article.