Get As Read Post As Write


Problem A CGI has to display a form, possibly with some items already filled out. When the user submits the form, errors or missing fields may require the form to be changed and resubmitted.

Solution Never embed a form inside a plain HTML page, especially if the site could fill in some details of the form based on state and history. The CGI (used generically to mean CGIs, servlets, ASPs, etc) should react to a GET by handing the form back to the user and react to a POST by taking action.

Consequences It's now possible to redisplay the form if there's an error, while keeping the code necessary to produce the form in only one place. Since the form display code is available during the form processing, an error can be handled by redisplaying the form and informing the user of the problem. No more "please go back and try again".

I've promoted this to a full pattern because it came up in a usability meeting we had the other day. It needs restating and expansion, but the rule still holds:

Any operation that results in data moving from the server to the user should be done with a GET. Any operation that involves data moving from the user to the server should involve a POST.

This isn't just (as originally stated) to make it easier to throw the form back up in case of an error, but also to make it easy for the user to bookmark the results. Examples of this include Wiki, the search on Yahoo, and in fact most search engines. It's sad that this is non-obvious, but (for me, at least), it was.
I agree with this, but found the pattern organization to be confusing. A suggestion: the problem statement isn't clear on why requiring the form to be changed and resubmitted is a problem. You get at the problem (code sharing) later, but not until after this reader did a huh? Consider taking one of the benefits and reversing it.

Also, having the code that generates and interprets the form in a single CGI has maintenance benefits, and makes it easier to build and maintain self tests (i.e., passing a magic token to the CGI generates a form prepopulated with data to test error handling).

On the minus side, if you want to put a form in the users face right away, you may need to turn you home page into a CGI. --DaveSmith
Another problem:

If your clients switch off cookie support and you need to support an "abstract session", you have little choice but to pass a session id with the form data. This will make the URL long and messy when you use GET.

If you need security, you may want to keep identifiers like the session-id or special keys out of the URL since some browsers send the address of the page from which they are departing to the next server. To avoid this, you need to "Read as post".

On the subject of modelling interactive web-services:

I would have thought that UseCases would be particularly effective for modelling interaction between users, a server and possibly some back-end logic. Suppose each use-case was given a unique identifier (with conventions for recognising <<uses>> and <<extends>> relationships.) You can ship this identifier back from clients with hidden form fields to simplify a lot of the server-side logic, and make it easier to reason about "state". See also: AbstractSessionPattern

View edit of April 10, 2012 or FindPage with title or text search