[LRUG] REST and Associations

jennifer lindner jen at jenlindner.com
Tue Feb 27 07:01:35 PST 2007


eleanor,

wow, that was really, really helpful!

this thread about REST, with all of the attending links posted along  
the way, has probably taught me more about REST and - these last  
questions, how it applies in specific, potentially confusing  
situations - than almost all of my other outside reading on the  
topic. thank you.

it's when something new is brought back to the world the way you know  
it (see search and pagination discussions below!), that you know  
you're  starting to get it. before then, when it's a completely new  
and unknown thing, why, it could be could be capable of anything,  
maybe it could fly or turn green, who knows ;-)

-jennifer

On Feb 27, 2007, at 12:10 AM, Eleanor wrote:

> Hi Roland,
>
> Apologies in advance but this is going to be a long reply, and
> probably not that helpful >8p
>
> On 22 Feb 2007, at 22:02, Roland Swingler wrote:
>> 1. From what I've read, I thought all urls were meant to be nouns in
>> restland - how does having /posts/1;edit give you any advantage over
>> /posts/edit/1 or /posts/1/edit ? A semicolon does not a noun make.  
>> For
>> me this highlights a possible weakness in thinking of everything as
>> nouns - see Steve Yegge's "Kingdom of Nouns" article -
>> http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-
>> nouns.html
>
> <rant>
> Rails' RESTful is a good approximation of the real thing, geared to
> an (X)HTML environment. Using raw HTTP (i.e. GET/PUT/POST/DELETE
> headers) there really is no problem with edits - an edit would just
> be a GET existing resource followed by a POST updated resource, and a
> new resource would be created using a PUT resource request. There
> would be no such thing as
>
> 	/posts/1;edit
>
> because that's unnecessary at the HTTP level.
>
> However in (X)HTML land your application has to provide an interface
> that allows a resource to be presented in an editable manner, hence
> the use of a parameter to a GET request to return a representation
> that can be edited by the browser. In this case you are not using
> 'edit' as a verb, but as a noun identifying the edit form itself. Of
> course the
>
> 	/posts/1;edit
>
> URI is a very non-standard usage as most people wouldn't think of
> embedding a semicolon in the URI itself but would instead use a GET
> parameter:
>
> 	/posts/1?edit=
> or
> 	/posts/1?action=edit
>
> which has implications for caching of the content. Blame the W3C for
> this annoyance - they've had more than enough years to add DELETE and
> PUT into the HTML specs, instead of arguing over <BLINK>, the correct
> usage of <I> and <B>, and all the other trivia that seems to obsess
> them.
> </rant>
>
> Of course these limitations don't apply if you're working on an AJAX
> application as it's then possible to send the full range of HTTP
> verbs :)
>
>> 2. What is the right way to do search? Are query strings still ok in
>> urls? Is search a seperate controller?
>
> A RESTful search should consist of a URI approximately similar to the
> search criterion, and your app would transparently do the search
> routing in the background, returning an index page listing the top
> hits. So for example:
>
> 	/books/authors/a-z/country/us	
> and
> 	/books/country/us/authors/a-z
>
> would both perform the same search and return the same listing of
> authors. This reflects the fact that both URIs refer to the same
> resource and that its index page is the natural place to list all of
> the matching authors. However nobody does this - probably because
> there is a common misconception that REST somehow mandates unique
> URIs for resources, which is not the case. Hence the usual
> alternative of:
>
> 	/books/search?authors=a-z;country=us
>
> which is not a valid REST request ('search' is a redundant verb), or
> the somewhat more RESTful
>
> 	/books?authors=a-z;country=us
>
> where GET parameters are being used appropriately to specify
> criterion. Of course parameters in GET requests have a habit of
> confusing caching servers, increasing traffic for popular searches on
> the originating server...
>
>> 3. Similarly what is the right way to do sorting/pagination? For
>> example when I GET /posts I may want to only return the top ten in
>> html - but what about in the xml respond_to do I return all of  
>> them or
>> just ten? Is the idea that *exactly* the same resource(s) are
>> returned, no matter the mime type or can _what_ is returned vary as
>> well as _how_ it is returned?
>
> Pagination could be handled using a URI such as:
>
> 	/recipes/1/pages/3?page_entries=30
>
> which makes proper use of HTTP parameters with a GET request. There
> is of course a Pagination object in Rails, but for many tasks it's
> somewhat restrictive and it's simple enough to roll your own.
>
> A common mistake with pagination schemes is to mandate the number of
> page entries on the server side, which is not where responsibility
> should lie (HTTP servers should not maintain state, even if it is one-
> size-fits-all 'default' state). With vanilla (X)HTML the client may
> need to be told the number of entries by scripts on the server as
> part of creating appropriate browsing links for the page, but web
> services and URI interfaces should be more flexible than that. After
> all, it's the client that understands the concept of pages and the
> client should therefore be able to specify how large it believes
> pages should be and which page it thinks it wants in the sequence -
> or some other meaningful pagination specifier. This would suggest
> alternative URIs of the form:
>
> 	/books/1?page=3&paragraphs_per_page=10
> or
> 	/recipes/1?start_item=91&items_to_list=30
> or
> 	/recipes/1/items/91-120
>
> and the server would either return valid content or a resource not
> found error (either a standard 404 or a redirect to an appropriate
> 'sensible' error response for an HTML browser).
>
>> 4. The urls nested resources produces only seems to make sense for  
>> the
>> new / index /create actions - by the time the resource has a  
>> unique id
>> it already has a unique url, because the id is unique - but there
>> doesn't seem to be any way to disable the urls you don't want.
>
> You've just eluded to the single biggest flaw in Rails' URI
> conventions. Exposing database IDs over the network is a very bad
> idea and everyone should write their applications to use public
> resource names rather than IDs. In real-world applications it will
> have minimal impact on database query performance (after all, you are
> using indexes I hope!) and at the same time will make your URIs much
> more robust. Otherwise you're handing implementation-dependent detail
> to any random third-party that wants to explore your application, and
> constraining your public interface to a static view of your data.
> You're also breaking a key tenet of user interface design - a URI is
> intended to be a human-friendly resource identifier and as such
> should use meaningful semantics wherever possible to simplify the
> user experience!
>
> Instead of:
>
> 	/posts/1
>
> you should favour:
>
> 	/posts/my-views-on-REST
> or
> 	/posts?title=my-views-on-REST&version=0.1
> or
> 	/posts?year=2006&month=December&category=REST&author=all
> or
> 	/posts/2006/December/REST
>
> none of which expose your database IDs, and all of which can point to
> the same resource, allowing users to remember whichever style of URI
> makes most sense to them as well as making educated guesses about how
> to search for other resources in your application.
>
> This is where the environment/routes.rb file comes in to play. Some
> useful resources on Rails routes include:
>
> 	http://www.pinupgeek.com/2006/5/24/rails-routing-demystified
> 	http://www.afreshcup.com/2007/2/9/basic-routing-in-rails
>
> but these all tend to be pretty basic. I've yet to find any really
> deep geek articles on the subject, although LRUGer Paul Battley has
> done some interesting work on a procedural alternative to the
> standard routing model so he might be able to suggest appropriate
> resources.
>
>> 5. For nested resources, how do you avoid a dirty great switch
>> statement in your controller if things can be nested under many
>> different resources?
>
> Rails tends to encourage one controller per view so if you've lots of
> big case statements in your controllers the chances are that you've
> too few controllers relative to your views. Also remember that
> multiple routes can all lead to the same controller/view  
> combination...
>
>> 6. What do you do when you want to create multiple objects at once?
>> What do you return in the location field in the xml response? or
>> update or destroy many objects at once? What happens if you want  
>> to do
>> ANYTHING to more than one resource at once?
>
> You could try using a similar approach to the one suggested above for
> search, in that effectively a multi-resource delete or update is
> analogous to a GET, so performing a POST with a form returned by the
> query:
>
> 	/books/authors/a-z;edit?theme=&
>
> would change the theme attributes on the specified range of
> resources. The returned URI for the location should probably be:
>
> 	/books/authors/a-z
>
> as that's the resource that in this case has been updated and an
> index.html would be returned to a browser (or index.xml, index.jpg,
> whatever other MIMI-type is requested).
>
> With regard to how many items to return in a request, this in general
> should be specified by the client (as mentioned above).
>
>> 7. How useful is ActiveResource - is anyone here using it? can you do
>> much more than find a list of resources/resources by id - like the  
>> sql
>> options in find()?
>
> The demo of it at RCE looked interesting as it'll allow complex
> automation pipelines to be built using a very similar API to that
> provided by ActiveRecord. However if it does rely exclusively on
> resource IDs I have a feeling it's going to cause almost as many
> problems as it will solve.
>
>> Any thoughts on any of these very very welcome - and as a call for
>> talk ideas was raised earlier I would really appreciate a talk on  
>> REST
>> that goes beyond the basics of here is a resource generated with the
>> scaffold - "look now I can find a record with an id with
>> ActiveResource" - anyone offering...?
>>
>> On a side note does anyone know if there is a group/mailing list
>> devoted to REST - I tried to find one the other day but google groups
>> came up blank :(
>
> A good place to start research the subject:
>
> 	http://rest.blueoxen.net/cgi-bin/wiki.pl
>
> which has links to other resources.
>
>
> Ellie
>
> Eleanor McHugh
> Games With Brains
> ----
> raise ArgumentError unless @reality.responds_to? :reason
>
> _______________________________________________
> chat mailing list
> chat at lrug.org
> http://lists.lrug.org/listinfo.cgi/chat-lrug.org




More information about the Chat mailing list