Been thinking about something lately and wanted to hear what others
thought. After watching the video[1] of DHH with the slides[2] I really
liked some of the ideas presented. Many people have noted the ugliness
of needing secondary actions since HTTP actions do not cover the full
range of CRUDness (i.e. the "GET /people;new" and "GET
/people/1;edit").
Also the need for occasional actions that fall outside the standard CRUD
("POST /people/1;closed").
Some people are just disturbed by the URL. That doesn''t bother me. What
bothers me is that conceptually we have two actions associated with the
request which just seems awkward. On the flip side since HTTP doesn''t
support arbitrary actions it seems we just have to live with this
awkwardness.
BUT, the other concept presented (using Accept headers, extensions and
mime types to determine what is returned) seemed to me to be the answer
to this awkwardness. The idea presented was to use the "Accept" header
(or as a fallback an filename extension) to determine what the user
wants. So:
GET /people/1
Accept: text/html
returns a HTML page of the person requested while:
GET /people/1
Accept: text/xml
returns a XML representation of that person. My question is what is the
difference between that and doing something like:
GET /people/1
Accept: application/x-edit
instead of
GET /people/1;edit
When we do:
GET /people/1
Accept: text/xml
we are saying "Give me the person with id ''1'' in XML
format". When we do:
GET /people/1
Accept: application/x-edit
we are saying "Give me the person with id ''1'' in a
editable format (HTML
form)". The same would apply to "new". So:
GET /people
Accept: text/xml
says "Give me people in XML format". While
GET /people
Accept: application/x-new
says "Give me people in a format that I can create a new person".
One more example.
POST /people/1
Accept: text/html
This says "Save person with id ''1'' in a manner accepts
HTML forms" while:
POST /people/1
Accept: application/x-closed
says "Save person with id ''1'' in a mannor that closes
it"
We could even use the file extension trick since sending Accept headers
can sometimes be difficult. So we might have:
GET /people.new
GET /people/1.edit
POST /people/1.closed
Of course all of this would map to the same actions in your controllers
as they do now. In the end all that is really changing is that we are
changing a ";" to a ".". But conceptually we are
transforming an request
with two actions into a request with one action but with different
formats requested. In my mind this provides a constancy since we are
already doing this when requesting XML, JS, mobile-content, etc.
I am curious what others think? Is this all crazy? Am I overloading
mime-types way to much? Traditionally we have considered the following:
GET /people/feed
as saying "Carry out the action ''feed'' on the list of
people. This
action returns RSS content." Now we do this:
GET /people
Accept: application/rss+xml
as now saying "Give me a list of people in RSS format". We have moved
from specifying an action to specifying a format. My question is why
can''t we do this for all cases. So while right now we say:
GET /people/1;edit
which means "Give me person with id ''1'' and carry out the
secondary
actions of ''edit''" we might be able to say:
GET /people/1.edit
which says "Give me person with id ''1'' in a format that I
can use to
edit that person".
I am interested to hear what others things.
Eric
[1]
http://blog.scribestudio.com/articles/2006/07/09/david-heinemeier-hansson-railsconf-2006-keynote-address
[2] http://www.loudthinking.com/lt-files/worldofresources.pdf