Quest for the Holy Rails

May 2, 2007

RESTing on Rails isn’t as Dangerous as it Sounds

Filed under: design decisions, rails — Jake Brownson @ 7:38 pm

I have decided to try and use REST design for my Pente project, and the purpose of this post is to ground readers on how I came to that decision.

There I was beginning to get comfortable with Rails. I was just starting to think I was hot stuff because I was learning the latest and greatest web framework on the tubes. Then I saw all this stuff about RESTful this and RESTful that. Well it turns out REST is yet another whole new can of worms.


No, RESTful Rails doesn’t involve closing your eyes while you program. REST stands for REpresentational State Transfer and was coined by Dr. Roy Fielding in his doctoral dissertation. Dr. Fielding is no slouch. Have you heard of the Apache webserver? He’s a co-founder. In his dissertation he essentially suggests we stick to the fundamental ideas in the HTTP standard when designing interactive web applications.

Most webpages today use two of the verbs HTTP defines: GET and POST. However, HTTP defines several others: HEAD, PUT, TRACE, DELETE, OPTIONS and CONNECT that aren’t supported by HTML forms and therefore not actively used in today’s web apps. REST design makes use of GET, POST, PUT and DELETE. REST also emphasizes the idea that the URI should not contain any verbs, only nouns and maybe some adjectives. The URI tells us what we’re doing something with and the HTTP verb tells us what to do with it.

Examples of non-RESTful URIs:

  • /employees.php?id=5&action=delete
  • /records/admin/create?documentid=45
  • /users/1;edit
  • /edit/users/1

Examples of RESTful URIs:

  • /users
  • /users/admins
  • /users/1
  • /users.php?id=1
  • /posts/1/12/2007/my_day
  • /posts/1/12/2007/my_day/comments
  • /posts/1/12/2007/my_day/comments/5
  • /posts/random

These RESTful URIs don’t really mean anything by themselves. For a webapp to service a request it needs to know what it should do something with and what to do with it. The URI tells you the former. With just the URI you cannot know what the client wants!

To get the complete story you also need to know the verb:

HTTP Verb Meaning
GET Receive a representation of the resource in the URI without changing anything
POST Create a new representation of the resource in the URI
PUT Update an existing representation of the resource in the URI with new data
DELETE Remove the resource identified in the URI

These should sound familiar to you. You’ve probably learned that Rails is designed around the idea of CRUD (Create, Read, Update, Destroy). Well these actions map quite well to the REST HTTP verbs.

HTTP Verb CRUD mapping
POST Create
GET Read
PUT Update
DELETE Destroy


Now you know what REST is, but so what? Why does it make a better app? There are many reasons. My favorite reason is that (at least in Rails) you get a nearly free web API by following RESTful techniques. Here’s a little bit of code generated for a games controller by Rails’ REST resource generator:

# GET /games/1
# GET /games/1.xmldef show @game = Game.find(params[:id])
respond_to do |format|
  format.html # show.rhtml
  format.xml  { render :xml => @game.to_xml }

The respond_to method make it easy to render the data in different ways. The RESTful generators automatically give you two formats: the standard HTML and a new XML format. Thanks to the .to_xml method we get built in on our models we just got a one line web API for this resource! REST is also just a good way to think about designing your app. If you use the REST design principles correctly it’s hard to end up with an ugly design. Finally by using the HTTP verbs as they are intended the browser and any proxies and routers that are relaying your HTTP between the client and server can do more intelligent caching with the data.

Just a minute here…

Remember how I said REST uses four HTTP verbs, but HTML only uses two? How can we write forms that delete or update resources if we can’t use the PUT and DELETE verbs? Well we really can’t be truly RESTful. Currently RAILS sort of sneaks the PUT and DELETE verbs in by assigning a “_method” parameter to fake it when setting up a form. My initial reaction to this was “yuck!”, and it still is, but I think it might be worth it. There is lots of ongoing discussion about the issue, but I’m not sure there will be a great solution until the HTML spec supports PUT and DELETE. In fact one of the URI’s I gave in the list of non-RESTful (/users/1;edit) is one that Rails uses when you generate a REST resource because nobody has come up with a perfect solution yet.

Don’t forget about one of REST’s big benefits. When used as a Web API you aren’t limited to GET and POST verbs. Any HTTP library worth its salt can make PUT and DELETE requests as well so there is no Javascript hackery involved. To experiment with a REST API you can use cURL (manpage) to generate pretty much any HTTP request you want.

Since it sounds like such a neat idea, and I’d like to have a web API for my Pente project I’m going to go ahead with REST design. I might get sick of all the javascript hacks and decide REST isn’t worth it, but I’m going to give it a shot.


  • What do you think about REST?
  • Do you think Dave’s RADAR is the correct answer to HTML’s failings?
  • How would you get around HTML’s limitations to implement a REST design?

Want to Learn More about REST?

This post doesn’t cover the technical details of how to use REST in your rails application because there are already other resources that do a great job of that.

Where to Next?

Look at my decision to use test driven development for Pente or follow along as I implement the project.


Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at

%d bloggers like this: