Post/Redirect/Get or Redirect after Post is an HTTP interaction pattern that can be used when developing web applications. I have been mentioning it quite a few times in my consulting work and thought I would take a stab a at diving a little deeper in the pattern and its benefits.

Post-Redirect-Get pattern

Basic Post Redirect Get pattern

The sequence diagram above shows how the pattern works to create a resource. First the client requests a form that is used to create the resource. The server obliges returning a HTTP 200 status code and the mark up containing the form.

<form method="POST"> <input name="somefield" type="text" />
    <input name="submit" type="submit" />
</form>

For this example the user enters data into all the required fields and submits the form.

The server receives the requests processes the data, realising the data in some backing store and returns a 3xx status code (redirect) to the client with the url for the object created in the store.

The client honours the redirect and makes a request for the URL returned in the redirect message. The server returns markup representing the new resource.

On the server side

Model View Presenter pattern (MVP) is derived from the Model View Controller software pattern that has proven to be very effective for UI base applications.

Model

represents the collection of objects containing the data and operations of the system. The model may be a Domain Model or not.

View

The view is responsible for rendering data to the user through the UI.

Presenter

The presenter is responsible for handling GET HTTP requests, retrieving the model from store and possibly manipulating the data to be available for the view.

Command

The command is a responsible for handling POST HTTP requests. Data presented to the server as part of the request is processed by the command to manipulate the model. Commands return a redirect URL that results in a subsequent GET request handled by a presenter. The diagram below illustrates the relationships between Model, View, Presenter and Command.

Model View Presenter Command

Statically-typed language implementations of these components revolve revolve around classes derived from ‘model’, ‘view’, ‘presenter’ and ‘command’. Frameworks based on dynamic languages might take a different approach with presenter and commands being implemented as methods on a single class.

Putting things together

The sequence diagram below is my attempt at illustrating the sequence of operations and client/server interactions that are present when combining PRG with MVP(C).

The sequence represents the following sequence of user interactions

  • Visit the site (home page)
  • Click on the /someform link
  • Enter invalid data and click the submit button
  • Review errors, correct the data and submit
  • View the result of the operation

Post-Redirect-Get-and-model-view-presenter-command

Each post request results in a write to the database and is followed by a GET request to retrieve data that was updated as a result of the POST. This may appear to be a significant overhead but it does ensure that no state is maintained in the server which simplifies load balancer configuration and the ability to upgrade servers with minimal disruption to service. Unless large amounts of data has been stored in cookies then the redirect-get is not expensive in terms of bandwidth but latency can become an issue.

Breaking up interactions simplifies the server code, each operation is represented by a method or class. These request handlers only need to handle the single request which avoids more complex logic to understand the client state. In PRG the data is represented in the URL and the HTTP verb (with some user related data in cookies perhaps).

A comment from a colleague:

The big advantage of PRG for me is that it opens the possibility of being able to return to partially completed workflows, and being able to return to long-running server tasks by bookmarking (or refresh buttons or back buttons in browsers) without worrying about duplicate form posts. – Tom Czarniecki http://watchitlater.com/blog/>

The MVP pattern does not separate request handling based on the HTTP verb. This separation helps encapsulate the difference in handling a GET and POST request.