Let's all get on the same page about what makes up a web app. Here are some concepts and terms for talking about it. Users have a clear conceptual model of a web app; this model should be well-understood by web developers and tools should take it into account. The below is a first draft and probably will need revision—I'm interested in feedback from active web app developers. Is this accurate from your point of view? Any nuances of the web it doesn't take into account?
What Web Apps Are
Every web app has a model, which is some body of information that the user wants to interact with (view and alter). To the user, the app offers a particular experience of interaction with the model.
The fundamental experiential units of the web are requests. This unit issues from the infrastructure of HTTP. A "request," for present purposes, is a round-trip exchange of data with the server which results in the browser (a) adding a new item to its history and (b) completely redrawing the page contained in the response. It is possible to redraw the page without such a request, and it is possible to get data from the server without redrawing the page, but it is not possible to add an item to the browser's history without a request.
Different application designs (in particular, ways of breaking down into requests) may offer different experiences over a model.
From an application designer’s point of view, a web experience is composed of two distinct kinds of requests, actions and views.
An action transforms the app's model and redirects the user to a view; an action should not display a page by itself (see below for an exception).
A view should not modify the model, but it does display a page to the user. This separation guarantees an important user expectation: that hitting “reload†will merely refresh the information I’m looking at; it never has consequences beyond my browser.
An action may display a page directly, if something has gone wrong in performing the action. In this case, hitting “Reload†has a clear meaning to the user: it means that the app should “retry†the action that failed. If an action succeeds, however it should redirect to a view, rather than display a page directly. Otherwise reloading the page will retry an already-performed action, when the user would expect it merely to refresh the displayed information.
What the designer or the user thinks of as an (informal) “action†may in fact display several pages to the user, accumulating local state over the course of that interaction, and modifying the model only at the end of the series of requests. For example, an “action†that deletes some object from the model may first confirm that the user really wants to do so, or a flight-booking app may have several pages of questions to collect before recording the ticket as booked. Call this series of requests a pipeline rather than an action; the intermediate pages are merely views in our terminology, and the final request is the only action. These intermediate views may need to store intermediate state information; but this state is ancillary to the model.
Sticking to this discipline (which, broadly speaking, good web apps already do) ensures that the browser's history accumulates a list of things the user saw, and not a list of actions taken. It is impossible to take unintended action by using the browser's history.