Me
About
Gallery
Company
Girl


Projects
Ruby on Rails
Basecamp
Highrise
Backpack
Campfire
Ta-da List
Writeboard


More
Feed
Archives

May 07, 17:11

Google: Recall, Developers: Improve

As I'm making the trip from Copenhagen to Chicago (and then on to San Francisco), I thought it prudent to take an airborne view of the latest bruhaha over Google's Accelerator. Yes, specifications such as the HTTP are important. Yes, POSTs are a better way of modifying data than GETs. We should all move in that direction. Backpack made the switch yesterday.

That being said, there's a reason why GETs was used in the first place. Just like tables were mis/used for styling, people will route around specs that doesn't allow them to do what they need to do. HTML is not a particularly friendly place to implement a RESTful interface, so people find other ways. Bend the rules to Get Stuff Done.

But standards improve. The table-based design have fallen from grace due to the strong support of CSS now available. When there's a better way available, most people will eventually follow it. But the switch doesn't happen over night. And it certainly doesn't happen because Google or RESTful purists would like it to. That's just not the way these things go.

So. Google: Recall the accelerator. Make it do no more damage in that real, imperfect world we're living in. Application developers: Let's route around the lack of support in HTML for a RESTful interface the best way that we can.

Rails will ship its next version with a link_to that looks just like a GET, but uses Javascript, or some other way, to do a POST. Since the HTML isn't moving forward, we'll just have to build on top and make it no harder than not to. We're doing that with Ajax, we can do it with REST.

(Just in case you didn't get the implicit message at the top. This message was posted from some 30K feet in the air while onboard the SAS SK943. $30 for an entire flights worth of 30-60kb/s satellite connection. Oh my, it's sweet.)


Challenge by Lawrence Oluyede on May 07, 18:39

Good job David, but let me ask, how can you fix link_to in a useful way? I mean this "Rails will ship its next version with a link_to that looks just like a GET, but uses Javascript, or some other way, to do a POST.".

Bye

Challenge by Eric on May 07, 18:40

I have to say, I'm incredibly unimpressed with your logic. You're trying to hide behind your language. Here are some examples:


Yes, POSTs are a better way of modifying data than GETs.


No, it is improper to use GETs to modify data.


Bend the rules to Get Stuff Done.


You didn't "bend" the rules, you "broke" the rules. And as far as "getting stuff done" you've released multiple products that did not adhere to core standards.


And it certainly doesn't happen because Google or RESTful purists would like it to. That's just not the way these things go.


Well, since you're such an HTML historian, perhaps you can tell me which forces were in play to push CSS to where it made table-based layouts obsolete. I'm not such a historian myself, but I'm willing to bet that people who said tables were the wrong way to do it were instrumentally involved.


And finally, standards are a way of making multiple, parallel projects work together by unifying the assumptions. That is the way things go. Objecting to standards compliance by calling them purists is rather lame. You screwed up, and yet you blame those that are adhering to standards.

Challenge by Eric on May 07, 18:43

And let me add one more thing. You consider your "RESTful" interface an innovation. Google considers their service an innovation. And yet there was a conflict. One innovation built on the standards; one violated the standards. Again, who is at fault?

Challenge by cboone on May 07, 19:17

Lawrence: What needs fixing? The new Rails link_to method is a proposed fix to the problem under discussion.

I believe that David means that it will appear to the end user to be a regular, old-fashioned, GET-based link, but will in fact be a POST, thus adhering more closely to the standard.

Eric: Hasn't this all been adequately covered already?

The standard (section 9.1.1 -- Safe Methods -- of the HTTP/1.1 RFC 2616) -- available for your reading pleasure at http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1 -- phrases the matter in terms of 'SHOULD' and 'ought'. Thus it seems clear that David et al. most definitely bent the rules, but did not break them.

Challenge by Ryan Tomayko on May 07, 19:44

Eric: chill out. You make some good points but you're trying to twist the world into working in a way it does not. It's a losing battle. The web is a complex ecosystem with millions of uncordinated agents adding new features all the time. This type of incompatibility is bound. Expecting people to follow standards that aren't supported well or that have no immediate value to provide is unrealistic.

Challenge by Vincent D Murphy on May 07, 19:56

David-

I am delighted to see this change of heart, and look forward to seeing Rails become a better framework by making it easier to do the Right Thing in web applications.

You may be wrong sometimes, but you always admit it when its proven and I respect that.

Eric: what Ryan said. David is doing the right thing here, in full public scrutiny, and I think you're over-reacting.

Challenge by cboone on May 07, 20:23

On further thought, it seems to me that full adherence to the standard demands that almost all links on web apps use POST rather than GET -- or that the standard itself is flawed (reductio ad absurdum).

After all, in most web apps even GETs that only retrieve (and thus follow the first half of the standard) are not always idempotent (and thus bail on the second half of the standard) since they have side effects that are not necessarily identical from case to case.

For instance: I have a web app that allows people to post ads. When you're creating a new ad, you can click on one of the standard navigation links (a retrieval GET) and thereby lose the data you've entered -- a side effect that is not the same as the side effects of clicking the exact same link when on another page. Thus, though the site's navigation is idempotent when taken on its own, it is not always idempotent when taken in sequence with other idempotent actions; thus those links should use POST rather than GET, per the standard.

One of the flaws here seems to be that client-side activities can change an idempotent action into a non-idempotent one, and it's hard for web apps to have any idea of those activities. The standard does not address this.

Should web apps try to track a user's activity client-side so that they may better follow the standard? No; that's instrusive, excessive, and counter to the general nature of the web.

Or should the standard (whether the official, written standar, or its accepted, colloquial cousin) reflect that things aren't always so simple as GETs are safe, POSTs are unsafe?

Challenge by John on May 07, 22:14

"Rails will ship its next version with a link_to that looks just like a GET, but uses Javascript, or some other way, to do a POST."

I'm sorry, that sounds like a horrible idea. I don't a mess of Javascript attached to every action link nor have I yet to see any good reason for switching all 'action' GET requests to POST.

I really hope this all link_to's are POST is optional and not the default.

Challenge by David Heinemeier Hansson on May 07, 22:49

Of course. The POST style will be the exception, not the rule. The majority of link_to links are still for things where GETs are the right thing. But you're right, it is going to be a bit messy underneath the covers. Such is the world when HTML's support is less than stellar for the REST way. But at least we can abstract it.

Challenge by Peter Cooper on May 07, 23:02

And let me add one more thing. You consider your "RESTful" interface an innovation. Google considers their service an innovation. And yet there was a conflict. One innovation built on the standards; one violated the standards. Again, who is at fault?

Google, because they violate the standards. The Accelerator does not honor robots.txt. It also passes sensitive data that users may not be aware of through their server. I consider this unethical. This is the worst thing Google has developed.

Challenge by Tom Moertel on May 08, 0:10

David Heinemeier Hansson wrote, "But you're right, [the POST implementation] is going to be a bit messy underneath the covers. Such is the world when HTML's support is less than stellar for the REST way."

Why does it have to be messy? Most of the contexts in HTML where POST-based submissions are appropriate allow for block content. That means a tiny form is perfectly acceptable.

For example, looking at the default HTML generated by Rails on a "list" action, the Show, Edit, and Destroy links for each record in the list appear within their own TD elements. Thus the Destroy link could easily be replaced by a small form containing only a submit button labeled "Destroy". (More precisely, a form element containing a div element containing an input element of type="submit".)

The only place where this substitution cannot be made is within inline content. For example, we can't replace a link in the middle of a run of text with a form. But then again, we almost never want to put the trigger for a dangerous action there, either, because it looks too much like a harmless hypertext link.

It seems that much of the arguments for Javascript hackery and messy implementations boil down to wanting to preserve the sexy, sleek look of links. Buttons, even with clever CSS application, are hard to pass off as links. But perhaps that is a good thing. There is a compelling design argument that says that the triggers for dangerous actions should not look as friendly and as inviting as everyday links.

Challenge by misuba on May 08, 0:50

And incidentally, HTML is moving forward: http://www.whatwg.org/

Challenge by Mark on May 08, 2:18

Bravo David.

I think this is a much better stance than your last post. As I said before, Google should fix their end but it is also important to remove dangerous GETs. Kudos for fixing Backpack so quickly too.

That said, the analogy between tables being misused for styling and GETs used for modification is not a very strong one. In the worst case, using a table for styling could mean some information is poorly or inefficiently displayed. A non-safe GET can remove important information from the face of the web. With one automated or unwanted *click* your well thought out and careful crafted post is sent to the digital void forever. In Instiki's case it was very fortunate (and probably due to good foresight on your behalf) that rollbacks were non-destructive.

It's clear, however, that there is a tension here between what web developers want to do and what the RFCs and specs say they should do. That tension is a good thing. It is what drives the incremental improvement of standards.

The real issue with this particular situation is one of risk. Until the standards change do you want to risk non-safe GETs? Is your users' data worth risking? Because of the consequences the only sensible approach, to my mind, is a very conservative one.

By all means, push for some change and make a big thing out of exactly why what Google has done is a problem. Get everyone thinking about it then hopefully those in a position to change things will. In the meantime, don't make your users casualties on the front-line of this fight.

Challenge by Nis Wilson Nissen on May 08, 10:52

This discussion reminds me of a George Bernard Shaw quote:

"The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man."

Challenge by Lawrence Oluyede on May 09, 10:25

Sam Ruby points at some proposals http://www.intertwingly.net/blog/2005/05/08/Taking-the-unsafe-GETs-out-of-Rails

Challenge by Christian Romney on May 09, 15:34

cboone wrote:
For instance: I have a web app that allows people to post ads. When you're creating a new ad, you can click on one of the standard navigation links (a retrieval GET) and thereby lose the data you've entered -- a side effect that is not the same as the side effects of clicking the exact same link when on another page. Thus, though the site's navigation is idempotent when taken on its own, it is not always idempotent when taken in sequence with other idempotent actions; thus those links should use POST rather than GET, per the standard.

If I'm understanding you correctly, you're talking about partially filling out a form and then navigating away and returning to the form where the information you typed is now gone. (Please correct me if I misunderstood). If this is your contention, then you have misunderstood safe/idempotent methods. The modification of data that is referred to is on the server side. The spec does not attempt to dictate how your user agent should behave with data that has not been transmitted.