It’s just data

HTTP Best Practices

David Heinemeier Hansson: A huge thanks to the team behind the Atompub specification. This document has been a massive eye opener to best practice use of HTTP in a RESTful fashion. I encourage everyone with an interest in web services to read it. It started an avalanche of ideas in my mind. This respond_to implementation is just one offspring of those ideas.

Nice to hear, but I’d like to point out a cautionary note about that one particular feature.

Don’t get me wrong, HTTP and REST are great stuff.  But just like everything else, there are a few pitfalls to watch out for.

My advice: some of these features can wait for Rails 1.2.

Meanwhile, it looks like DabbleDB has added the Atom API to its plans.


It’ll be interesting to see how Rails 1.5 interacts with Google Web Accelerator.

Posted by Robert Sayre at

It’ll be just as interesting to see how java 1.6 handles the Google web accelerator.  Or python 3.0, or C++0x or ...

As I’ve said before,  there’s nothing in rails itself which causes trouble with the Google web accelerator.  It’s just application code which chooses to ignore the request method,  that’s just as easy to do in any other programming language.

Posted by Michael Koziarski at

If you really need to send different formats of the same information to different clients, I think Content Negotiation is the best way to do it. But only use it when you need to.

The issues raised on BitWorking are simply solved by giving each representation a different URL and adding a Content-Location header to the conneg response. Then you can use a specific URL when you want a specific representation, and the conneg URL when you want the client to choose.

Posted by Sjoerd Visscher at

As I’ve said before,  there’s nothing in rails itself which causes trouble with the Google web accelerator.

Michael, as you know, I am definitely a fan of rails, but I have to say that that’s a cop out.  Rails favors convention over configuration, and one of the hallowed conventions of rails is to map URIs to :controller / :action / :id.

Rails even provides ready made scaffolding that will handle delete actions in this manner.  Such an approach has pluses and minuses.  Rails even attempts to mitigate some of the downsides with confirm actions.

Net: saying that there’s nothing in rails itself which causes trouble with the Google web accelerator is a bit of a stretch.

Posted by Sam Ruby at

Michael K, given the other examples you used, I think you wrote ‘Rails’ when you meant ‘Ruby’. Which makes sense, but doesn’t negate Robert’s point.

Posted by Michael Bernstein at

Net: saying that there’s nothing in rails itself which causes trouble with the Google web accelerator is a bit of a stretch.

I certainly agree that the convention of :contoller/:action/:id doesn’t prevent you from deleting on a GET.  But neither does delete.php,  or DeleteSomethingOrOtherAction with struts.  JSF get’s a pass because you basically can’t do GETs.

1.1 will ship with verify() methods in the scaffolds preventing GETs from deleting items.  With explanatory comments saying that GETs should not be used for actions which change state.

So we’re doing our best to encourage best practises, Beyond that I’m not sure what we could add,  any thoughts before we branch for 1.1?

While I’ve seen some people suggest that we make the developers explicitly mark actions as ‘responds to get, responds to post’, I think that’s too much software.

Posted by Michael Koziarski at

Michael, I think it’s important to keep an open mind here. Rails has been very successful with the approach it has taken, and the framework is undeniably well-executed in almost every way. That said, there was a time when Java was steamrolling everything in a wave of hype, despite making glaring mistakes with well-known solutions that had been around since the 1960s. To put it in perspective, I feel the same way about your answers as you do about James Gosling’s comments on Ruby.

I apologize if any of the following comments are outdated with regard to Rails. I haven’t used it in a while.

I certainly agree that the convention of :contoller/:action/:id doesn’t prevent you from deleting on a GET.  But neither does delete.php, or DeleteSomethingOrOtherAction with struts.

That’s correct, and those approaches suck, so there is no reason to imitate them. HTTP has a thing called methods, which is where the action belongs. I understand that browsers are dense in this area, so the following hack is necessary: the page starts out with form buttons, and the ‘method’ is encoded in a POST param. Following that, onload JS executes and transforms the DOM into the visually appealing style you want.

The key here is to remove actions from the URI, and start treating the addresses as nouns, always. I don’t think it would be much of a change for Rails. The dispatching would have to work on Method+POST parameters instead of GET parameters. The impedance mismatches caused by the current approach are pretty significant, and they will never go away. I routinely encounter bugs in 37Signals apps that are fallout from putting actions in URIs. The GWA fiasco is just a particularly rough example.

In a way, I think this is all fallout from the Java HTTPServlet API. Something like Jetty’s Resource and ResourceHandler would work far better. Greg Wilkins was way out in front: Servlets Must Die. I know you’ll find the API in Jetty Javadocs disgusting in that special Java way, but I think the underlying ideas are really good, and certainly easier to use with HTTP than the model Rails has inherited from Struts.

All that said, you’ve got a big user base now, so I know that any changes in approach will have to be gradual and perhaps partial.

Posted by Robert Sayre at

Sam Ruby: HTTP Best Practices

[link]...

Excerpt from del.icio.us/sekimura at

"CRUD! CRUD! CRUD!": DHH

Well, ok he didn’t exactly do a Steve-Balmer-jumping-around-the-stage thing. But what he was driving at this evening’s keynote is extremely liberating: What if every controller does only* CRUD (create, read, update, destroy)? (Note: DHH understands...

Excerpt from wannabe3.1 at

Add your comment