Rest

I’ve been looking into RESTful approaches lately. Everything I know
my dog, Lelu, taught me.

REST (REpresentational State Transfer) is an architectural technique
for networked applications first described by Roy Fielding in his
dissertation at UC Irvine-- excellent work, especially considering
the tempting proximity of Newport Beach. As Lelu described it to me,
REST strives for simplicity of communication thereby putting greater
weight on the structure of the data being transferred. The success
of the web itself is due to the simple communications the web is
based on (GET, POST) which enable easy communications without pre-
coordinating the communication rules. The arguable failure of
remote procedure call approaches (XML-RPC/SOAP e.g.) is due to the
high-cost of pre-coordinating communications. That’s pretty
intuitive, right? The more work you have to put in before you can
begin to communicate the less likely you are to communicate. REST
embraces that which you’ve probably cursed at some point or other,
the stateless protocol. Statelessness is why you’ve got to do all
that extra work in your web applications to keep track of the state
of the app for your users.

Links to REST basics:

http://66.102.7.104/search?q=cache:uCkFMHAh5b0J:naeblis.cx/rtomayko/
2004/12/12/rest-to-my-wife+how+i+explained+rest+to+my+wife&hl=en
http://rest.blueoxen.net/cgi-bin/wiki.pl?FrontPage

In REST, resources (like files) are universally locatable via a
common syntax. In HTTP this is done almost entirely with the uniform
resource identifier we all know and love, the URL. The communicated
actions are simple. The data, though, may be complex. And the
actions on the data that aren’t communicated across the network may
be complex. I had to ask Lelu to repeat this a couple of times and
she had me imagine a typical web client/server scenario. The ideal
of REST, she said, is a case where there may be a multi-thousand
table database on the server side and lots of server activity on that
data, and there may be a lot of activity performed on the data by the
client on the client side. And there may be a lot of data flowing
between the two. But the REST ideal is one where the actions
communicated between the client and server are very simple, perhaps
only 4 verbs: GET, POST, PUT, DELETE.

As has been pointed out there are parallels between the basic
database verbs, basic web app verbs, and basic HTTP verbs:
database:
insert select update delete
web app (crud):
create read update delete
HTTP:
post get put delete

So, the data is rich and the transmission verbs are really limited.
The communication is always simple-- a basic verb + a resource
addressed by a URL that the verb acts on. What if we structured our
networked applications to streamline our transmission verbs down to
these 4 but paid more attention to the richness of our data? At this
point my dog started barking excitedly. The claim is that a lot of
great things happen:

–There’s great congruence between what the transmission (HTTP), what
the web app does (crud), and what the database does (insert/read/
update/delete), which streamlines the application.
–Resource addresses (URLs) are always resource addresses and not
mucked up by gobblygook or addresses that have verbs mixed in (http://
mywebapp.mydomain.com/myProtocolisPerl?myVerbIsDelete?MyUserIs?Bob).
Mapping the web is now much easier.
–The application will get a lot more use because everyone counts on
a simple, consistent interaction based on the formula of a simple
verb + URL-addressed resource that doesn’t requires any pre-
coordination.

Slightly more advanced REST links:
http://webservices.xml.com/pub/a/ws/2002/02/06/rest.html
http://www.xml.com/pub/a/2004/12/01/restful-web.html
http://www.prescod.net/

“O.k., that’s sort of interesting, but I’m not sure any of this is
actually practical knowledge which can help me build my rails apps,”
I said. Lelu bit me in the leg. “Ouch.” She panted a lot while
explaining that, even if I wasn’t building a web service app that
exists to feed data to another app rather than to a human, that
following REST principles will help me more quickly build regular
human-used web apps. The basic Rails application controller actions
are: index, new, create, show, edit, update and delete. If you set
up a controller for each resource then the odds are that you won’t
have to think much about your controller actions; you’ll just need
some subset of these 7 actions. Lelu seemed to be speaking doggie-
speak again. “What do mean ‘resource’?” I asked. “And 7 actions
doesn’t seem to match up very well with the 4 core actions we talked
about earlier. What gives?”

O.k., this is where the pedal hits the metal. “Resource”, as a term
is used by RESTafarians to refer to a conception of data that is
richer than we normally think of data. Remember the REST theme:
transmission verbs are simple; resources (nouns) are rich. So, it’s
not just your models that are resources. Resources are not just
simple nouns like products or users or dogs (that one’s for you,
Lelu). Your models will mostly map to db tables that are probably
simple nouns like these. Rich data tracks not just simple objects
with simple nouns but will also track things that are less like
prototypical nouns-- relations, events, and states, for example.

Lelu said that my models will track simple nouns while my controllers
will track rich nouns, i.e., resources. In general, the richness of
a resource increases as it moves from the db → model →
controller. So, you might want a controller for each model, but you
have to figure out which relations, events, and states are important
to you and build a controller for each of those resources as well.
So, your controllers will be a superset of your models. You might
have a controller to describe all the actions that can occur on a
product as it’s described by the product model. But you’ll also have
a controller for events like deliveries and a controller for the
states of things like sessions.

Lelu’s guidelines:
db tables-- build tables to track simple nouns
model-- build a model for each db table as a simple noun. Also build
a model for each other basic noun that isn’t in the db. Include only
model methods that always happen on each of those objects (i.e.,
very closely bound to them). Models are a superset of the db tables.
controller-- Build a controller for each resource (each noun object,
broadly construed, that you need). A superset of models.
controller actions-- Should be a subset of the following: index,
new, create, show, edit, update, and delete.

In general, with REST, your models and your controllers will grow in
number (reflecting richer data), but the number of controller actions
will shrink. Lelu put her foot, er, paw on a note which read: these
are good guidelines for how to think about building a RESTful Rails
app, but obviously aren’t absolutisms. [Lelu uses big words like that
sometimes.] Obviously, if you don’t need the data from a particular
table in your app you don’t model the table, and if a non-simple noun
like degree_of_satisfaction_with_post_industrial_capitalism is really
important for your app then you put that in the db. And Lelu didn’t
seem to worry that having a controller for each resource might
compromise the model-view-controller structure.

Scott R.'s summary of a refactoring with REST principles:
http://scottraymond.net/
DHH’s RailsConf presentation and slides:
http://blog.scribestudio.com/pages/rails/
http://www.loudthinking.com/

How do the 4 core transmission verbs match up with the 7 core html
web app actions (index, new, create, show, edit, update, and
delete)? Well, part of the mismatch can be solved by realizing that
every HTTP transmission includes an action + a resource URL, and if
each resource URL can be either singular or plural that gives us 8
possible combinations, which should be more than we need. The core 4:

action-- –
url what it
does–
rails idiom–
POST /products
creates a new
product create
GET /products/1
retrieves, i.e., shows some product with some id show
PUT /products/1
updates some product with some id update
DELETE /products/1 deletes
some product with some id delete/destory

There are at least 3 more actions we typically need to perform as
rails developers. We need to get a list of all products. No
problem. We just leave off the id and use a GET request:

GET /products
retrieves all the
products index/list

We also need to bring up a new form so we can add info to it before
posting it. Strictly this is a new resource, a form that’ll be
filled in, which we can represent with a new resource identifier, “new”:

GET /products/new
retrieves product
form new

We also need to be able to edit an existing product. Here is where
it’s been suggested that we take some liberty with the strict REST
guidelines:

GET /products/1;edit
retrieves a product in an editable form edit

We’re using the ugly syntax with the semicolon to illustrate that
we’re retrieving a resource under some aspect, in this case, under
the aspect of editability. This is a bit weird because we’re
potentially getting tangled into confusions about where aspects begin
and resources end. Is a product in an editable form a new resource
or just an aspect of a resource? Hmmm . . . . There are still some
combos available-- POST products/1, PUT products, and DELETE
products. But none of these makes sense for requesting an editable
form of a resource. Lelu is worried that, since there are limitless
aspects of a any given resource, and aspects are moving closer to
verbs that we’re moving down a road to putting verbs in what should
be strictly the address for a noun resource.

The 7 versus 4 mismatch problem isn’t really a problem except in this
last case. Maybe the ugly syntax will stay.

The other problem is the fact that the HTTP standards don’t require
that PUT and DELETE be supported in browsers. But this isn’t really
an obstacle. Until browsers and standards “catch up” with Rails,
they are simulated with a hack that uses a POST request in a hidden
field that sets method=PUT or method=DELETE.

O.k., so how do we actually implement a RESTful app in Rails? Well,
ActiveResource has been developed by DHH which let’s you get ahold of
a resource that’s got a URL and then perform 5 basic verbs on it:
–find
–update
–create
–destroy
–list

RESTful app services crank out (at least as a first step) XML, so the
2 rails action that exists specifically to get either a blank html
form (new) or a product’s edit form (edit) aren’t included.
ActiveResource lets you write code that will properly format requests
to talk to an existing RESTful web service. See Ryan Daigle’s article:
http://www.ryandaigle.com/articles/2006/06/30/whats-new-in-edge-rails-
activeresource-is-here

But the remaining question is, how to you build the server side of a
Rails RESTful app? Lelu is guessing that by Rails 1.2 ActiveResource
will be included with a system that will make it easy for you to
respond to the kinds of requests that ActiveResource generates.
Right now you can either:
a) roll your own system
see Matt Bidulph’s effort:
http://www.xml.com/pub/a/2005/11/02/rest-on-
rails.html?page=1
Or BenStiglitz’s effort:
http://rails.techno-weenie.net/tip/2005/12/31/
accepting_xml_or_yaml_in_your_rest_api
b) use the RESTful-Rails plugin
c) use the simply_RESTful plugin

Some plugin background:
http://microformats.org/wiki/rest/rails

Lelu’s knowledge of Rails on REST is pretty well tapped out at this
point, which is unfortunate because she’s motivated me to write a web
service that will serve up XML RESTfully. I’m not sure which plugin
to use, though. Perhaps simply_restful? And I don’t know how to
implement authorization RESTfully. ActiveResource seems to indicate
that there will be some kind of credentials system (?) Perhaps an IP
check would work for my purposes.

Lelu, the dog &
Russ McBride, PhD Candidate
Philosophy Dept.
314 Moses Hall #2390
University of California
Berkeley, CA 94720-2390
510-558-1662
[email protected]

Very nice writeup, indeed. :slight_smile:

Thanks for the complement, Bosko.

Best,
russ

Yeah, you rock Russ!

Umm… Lelu is a very knowledgeable dog, better than me… :slight_smile:

Thanks for this very nice write up. I just started on this RESTful
concept and have a hard time to adjustifying it.