RESTful Rails

Today I decided to get my head around REST and, more specifically, whether and how I should use it in my Rails development projects.

REST (or REpresentational State Transfer – see Wikipedia), is all about resources. As I understand it, in a perfectly RESTful application, every object is resource with a unique identifier (in this case, a Web URL). Any resource can be created, deleted, updated or simply viewed. These operations correspond to the HTTP methods of POST, DELETE, PUT and GET respectively.

Suppose we have an application with a class called User. One instance of that class may have the following URI:

http://dummy.com/users/3

To read this user, we GET http://dummy.com/users/3.
To update the user, we can PUT data to http://dummy.com/users/3.
To create a new user, we POST to http://dummy.com/users.
To delete the user, we DELETE http://dummy.com/users/3.

Previously, in a traditional, non-RESTful environment, rather than using these different HTML methods (in particular, PUT and DELETE), you might have something like this:

To read the user, GET http://dummy.com/users/3.
To update the user, we can POST data to http://dummy.com/users/update/3.
To create a new user, we POST to http://dummy.com/users/create.
To delete the user, we might GET http://dummy.com/users/delete/3.

For GET, PUT, POST and DELETE to work, your Rails application needs to know what to do with them when it receives them (otherwise, for example, how would it know whether you were reading, updating or deleting a user?) To tell Rails that you want to treat Users RESTfully, you specify so in the routes.rb file:

map.resources :users

This has the effect of mapping the GET, POST, PUT and DELETE of the URI to functions show, create, update and destroy in the associated controller. This mapping means that our application will handle such requests appropriately. But how will those requests get generated in the first place? Generally by the user’s browser following links that we’ve offered it. So the question is, how do we generate appropriate links?

We can generate RESTful links by using helper methods that are also (very handily) supplied by the resource declaration.

 
Named Route Helpers
============ =============================================
account account_url, hash_for_account_url,
account_path, hash_for_account_path

new_account new_account_url, hash_for_new_account_url,
new_account_path, hash_for_new_account_path

edit_account edit_account_url, hash_for_edit_account_url,
edit_account_path, hash_for_edit_account_path

So, for example,

link_to 'See user profile', :controller => 'users', :action => 'show', :id => @user.id

might become

link_to 'See user profile', user_url(@user)

I converted a simple application to be mostly RESTful this afternoon, and switching to these helpers cleaned up the code considerably. I found that I did have a number of operations that couldn’t easily be mapped to a RESTful equivalent. It will be interesting to see whether, with a RESTful mindset, I can find a neater way to accomplish them.

In the meantime, for more details about taking a RESTful approach to Rails, have a look at the Rails API documentation.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *