I’ve been looking at REST for a couple weeks now and I’ve determined that the next new project I start will be under REST.
What is REST?
REST is a standardized way of building complexed web interfaces for CRUD objects. CRUD is great conceptually, but its lack of strict standards makes it common to build separate interfaces for different formats (xml, javascript, html, rss, atom, etc…) and also creates the need for complex transfer protocol for handling interactions between servers (SOAP, CORBA, and other RPC standards). REST represents broad ranging standardization as well as making room for Active Resources which is the future of the RPC world.
For the most part, Rails already has a pretty standardized CRUD interface, so the first question I asked myself is:
So what changed?
As I perceive it, the majority of the changes take place in the routing. There are a lot of functions that are automatically generated and become handlers, connecting the html links and forms with the generated routes. REST also enables you to setup cascading objects while keeping pretty URLs.
Routes
Rails developers are pretty accustomed to URL’s that look like :controller/:action/:id followed by a query string with anything else. Under REST the most standard actions do not appear as part of the URL (new and edit are exceptions to this). The are now implied by the way in which the URL is called. Methods, formerly just POST and GET (think forms) are now POST, GET, PUT, and DELETE mapping directly to Create, Read, Update, and Delete. PUT and DELETE are indicated with hidden fields in browsers where they are not available as methods.
Functions
With all these default routes, it can be cumbersome a pain to assemble all the paramaters needed to create a URL or worse attempting to define URL’s explicitly. So to link everything together REST automatically generates functions that will take in paramaters and spit out either URL’s or hashes of paramaters needed to generate URLs. A plural function name implies that you are working with multiple objects or creating a new object while singular indicates that you are viewing or operating upon that object. When these functions generate URL’s they don’t continue to reflect the plural/singular…
Path Examples:
| Function |
Method |
Path |
Action |
| objects_path() |
GET |
/objects |
index |
| object_path(id) |
GET |
/objects/:id |
show |
| new_object_path(id) |
GET |
/objects/new |
new |
| objects_path() |
POST |
/objects/ |
create |
| edit_object_path() |
GET |
/objects/:id;edit |
edit |
| object_path(id) |
PUT |
/objects/:id |
update |
| object_path(id) |
DELETE |
/objects/:id |
destroy |
Each example has three functional counterparts, one for generating hashes, another generates complete URLs, the last one adds formatting information.
object_path(:id) becomes hashed_object(:id) or object_url(:id) or formatted_object_path(:id) respectively.
Cascading Models
So most Rails programmers have run into the situation where your passing 2 or more foreign keys along with your objects information.
Ex. User has_many Books has_many Chapters etc…
And when you go to make a modification to a chapter you want to make darn sure this user is editing his own books and not someone else’s. So you pass foreign keys, into the chapters controller every time anything happens so that you can track scope. The RESTful approach allows all of this to become implicite. Rather than passing foreign keys along as auxiliary paramaters they are now passed as part of the route. So you end up with URLs like
http://www.example.com/users/:user_id/books/:book_id/chapters/:id
which is way more intuitive than
http://www.example.com/chapters/:id?user_id=:user_id&book_id=:book_id
as it occurs so often in my own applications.
Advantages
More security: with every route explicitly specified it’s more difficult to allow access to critical system features without doing so intentionally
More Standardized: If you need to work with someone else’s code it’s convenient if they are using the smae standards driven conventions that are ingrained in your head.
More concise URLs: As many actions are removed from the URL
More descriptive URLs: As cascaded objects are represented in a more intuitive way the URLs become more human friendly
Active Resource: Ultimately REST paves the way for Active Resource. There is a lot of minor prettying up for which REST can kind of justify itself, but as Active Resource comes into its own I predict that a lot of people will begin to operate within REST just because it gets them to Active Resource.
Disadvantages
Learning Curve: So Rails itself requires a pretty avid fan to survive the initial learning curve. You have to have some sense of object oriented programming, database design, software testing, etc… just to make it to your first production launch. REST is another learning curve, with conventions to memorize and a little bit more magic to come to terms with.
Conclusion:
REST is worth it. If you’re reading this then you’re doing the right thing by keeping your eye on the horizon. When this arrives, bringing Active Resource with it, I look forward to seeing how the industry reacts. This is the kind of stuff that bumps Rails up into the niche occupied by SOA and so many other infinitely more complicated frameworks. Standards make corporate america go round, and this is bound to turn some heads.
Learn more:
PeepCode Screencast & Cheatsheet
Detailed Wiki Article
How this stuff works, and more on Edge Rails
General Hype:
Article covering “Why is REST important?” in dialog form
More of the same
Both of these came from LoudThinking which you should be reading if you’re not already