RESTful URL reference on Microformats wiki

Hi all,

With a little help from DHH, I've put together what I hope is the definitive guide to RESTful URL conventions for Ruby on Rails (2.0):

http://microformats.org/wiki/rest/urls

I would appreciate y'all talking a look at it, as the goal is to evangelize these conventions to the larger community, to encourage interoperability. In particular, let me know if you have links to other relevant resources and/or efforts.

Thanks!

-- Ernie P.

Nice guide! It’s clear, concise and definitely useful.

One important technical detail needs mention, and that is emulating PUT and DELETE over POST with the “_method” parameter. Current web browsers should be able to consume REST resources. This may be a hackish little detail, but don’t forget that you’re trying to define a common interface here to “ensure interoperability”.

While you’re talking about HTTP methods you should also mention common HTTP responses with REST other than common 200 or 404. They’re defined in the HTTP spec, but listing them for informative reasons wouldn’t hurt.

Hi all,

Nice guide! It's clear, concise and definitely useful.

Thanks for the many comments. A revised version is now up at:

http://microformats.org/wiki/rest/urls

Specifically:

http://microformats.org/wiki/rest/urls#Methods http://microformats.org/wiki/rest/urls#Response_Codes

Please let me know if there's anything else, especially links to additional relevant resources.

Best, -- Ernie P.

It'd be nice to have a section on RESTful url helpers. See:

http://www.ryandaigle.com/articles/2007/6/6/what-s-new-in-edge-rails-nested-resource-restful-url-builder#comment-form

  I've had problems trying to use these in the past...

Kevin

We had favorable responses to the "REST 101" series we did a while ago on our blog: http://www.softiesonrails.com/search?q=rest+101

Feel free to include the link if you think it's appropriate.

Jeff

This sentence should be rephrased: “Note that most browsers do not currently support PUT and DELETE, so those need to be implemented using a POST with an “?_method=” argument.”

It should say:

“Since most browsers do not currently support PUT and DELETE, those methods have to emulated over POST by providing a “_method” parameter with a value of “PUT” and “DELETE”, respectively.”

Thanks for the many comments. A revised version is now up at:

rest/urls - Microformats Wiki

Specifically:

rest/urls - Microformats Wiki rest/urls - Microformats Wiki

Don't forget the 422 Unprocessable Entity status code. You'd use it when the request is syntactically valid, but still contains invalid information. An example of this would be if someone sent an valid XML document, but one of the elements contained data that didn't meet the validates_* constraints in a model.

I usually reserve 400 Bad Request for the most generic of errors not covered by any other 4xx status codes, which is fairly rarely in practice.

Please let me know if there's anything else, especially links to additional relevant resources.

How about mentioning conventions for searching using query strings that I've seen in ActiveResource? Any extra params you send through to the find() method are added to the query string. Here's an article exploring different conventions for search:

   http://woss.name/2007/07/22/convention-for-restful-search-in-rails/

Hi all,

With a little help from DHH, I've put together what I hope is the definitive guide to RESTful URL conventions for Ruby on Rails (2.0):

rest/urls - Microformats Wiki

I would appreciate y'all talking a look at it, as the goal is to evangelize these conventions to the larger community, to encourage interoperability. In particular, let me know if you have links to other relevant resources and/or efforts.

Ernie,

Is there a restful convention for creating or changing association attributes that relates resources to each other?

For example I have a series of Activities each of which can cover many Subjects and Subjects can have many Activities. I can find scoped collections using nested resources. If:

  /subjects/5 => biology

Then

  /subjects/5/activities

Will return all the activities that cover the subject biology.

Now I'd like to add the subject biology to activity 18 but I don't need to update any other part of the activity resource. It might be clear in a RESTful way to do this:

  /subjects/5/activities/18/belongs_to

A more natural language url form might look like this:

  /activities/18/belongs_to/subjects/5

Of course since Activities can have many Subjects and Subjects can have many Activities then there is either a join table to connect the two models or a richer has_many :through table. A plain join table has no resource manifestation other than the relationship between the two resources -- the records in the join table have no ids that refer to them specifically.

Hi Dan,

Don't forget the 422 Unprocessable Entity status code. You'd use it when the request is syntactically valid, but still contains invalid information. An example of this would be if someone sent an valid XML document, but one of the elements contained data that didn't meet the validates_* constraints in a model.

Where is that documented? I didn't see it on:

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

How about mentioning conventions for searching using query strings that I've seen in ActiveResource? Any extra params you send through to the find() method are added to the query string. Here's an article exploring different conventions for search:

    http://woss.name/2007/07/22/convention-for-restful-search-in-rails/

That's a great suggestion, but right know there doesn't seem to be any "standard" for how to do it. Many if resource_search gets standardized (and integrated into Rails) then we can make *that* the convention...

-- Ernie P.

Hi Ernie,

Don't forget the 422 Unprocessable Entity status code.

Where is that documented? I didn't see it on:

HTTP/1.1: Status Code Definitions

It was added by the WebDAV project.

Here's the ticket in Trac that made ActiveResource start to treat a 422 as an invalid resource:

   http://dev.rubyonrails.org/ticket/7097

If you follow the discussion linked to from this ticket you'll see a post from Roy Fielding, where he suggests 422 as sufficient for the purposes of reporting that the request body was syntactically valid, but semantically invalid -- that the server is unable to process it.

Prior to Roy's post people were talking about creating a 418 Invalid status code, until he pointed out the previously defined 422.

How about mentioning conventions for searching using query strings that I've seen in ActiveResource? Any extra params you send through to the find() method are added to the query string. Here's an article exploring different conventions for search:

    http://woss.name/2007/07/22/convention-for-restful-search-in-rails/

That's a great suggestion, but right know there doesn't seem to be any "standard" for how to do it. Many if resource_search gets standardized (and integrated into Rails) then we can make *that* the convention...

It sort of is a convention right now in ActiveResource, although not all Rails apps make use of it. In the docs [1] for ActiveResource#find it shows the following example:

   Person.find(:all, :params => { :title => "CEO" })    # => GET /people.xml?title=CEO

I admit we're a long way away from real standardization on the server side though..

[1] http://edgedocs.planetargon.org/classes/ActiveResource/Base.html#M001761

Personally, for search, I find that /people.xml?q=a_ferret_compatible_query_or_similar is nicer than the above, and more flexible, in general. Yes it's RPCish, but this is one of those times where loosening the metaphorical bolt is warranted, I think.

Also, what's the best practice w.r.t. URL nesting for polymorphic resources? We try to limit ourselves to not nesting more than 2-levels deep (e.g., /posts/1/comments is 2-level deep). One additional level is OK as long as it's due to a namespace. So /admin/posts/1/comments is ok. What do you think?