Sound Advice - patterns

Tales from the homeworld

My current feeds

Published: Sun Sep 21 23:21:56 EST 2008

Updated: Sun Sep 21 23:21:55 EST 2008

Enqueue

Intent

Create a series of entries in a server-maintained set or queue.

Motivation

A business to business order processing system requires a reliable means of submitting, updating, and cancelling purchase orders. The system components at either end were developed by separate vendors to fit with each company's IT infrastructure. Both customer and supplier businesses require their side of the system to interoperate with other suppliers and with other customers they may have, respectively.

Each business upgrades their capabilities in line with their own business objectives. This often means that early adopters have moved on several times before the most conservative businesses make a jump to the latest approach and standards. In the mean-time, any given component on the server or client side must face an eclectic mix of counterparts and must interoperate with them correctly.

The Enqueue pattern is focused around the creation of server-side records in this message exchange. The PUT Pattern is used for subsequent updates and deletion requests.

Applicability

Enqueue is appropriate whenever the objective is creation of one or more pieces of server-side state based on information available to the client.

Structure

Enqueue pattern structure

Participants

Client
  • Keeps a base URL that provides context for the Create operation
  • Is capable of encoding its information in any form that it can legally and reasonably be encoded to.
  • Selects the most appropriate encoding based based on an initial guess. Subsequent requests are based on the on the supplied weighted acceptable types list if a Type Not Understood response is returned.
  • Issues the Create request
  • Is responsible for overall successful execution of the operation, including modifications to the request and resubmissions of the request
  • May or may not be able to determine whether the Create was successful or not when its response is lost, depending on the implementation
  • May or may not be able to control the order in which Create operations are processed, depending on the implementation
  • Aborts the operation on a failure response, on a resubmission response that cannot or will not be satisfied, or on a lost response after too many retries.
Server
  • Checks that the type of the document is understood before performing significant processing
  • Selects the kind of object to create based on the supplied base URL
  • (optional) Is configured with mechanism to require the client to resubmit their request with or without modifications
  • Allows the Create to operate initially
  • May provide a mechanism by which the Create operation is safe to repeat
  • May provide a mechanism by which a series of Create operations are guaranteed to be processed in order
  • Is capable of parsing all forms that the data might be encoded in that are semantically rich enough to use
  • Selects the right parser implementation to use based on the returned document type
  • Returns a Success response only once the creation can be considered permanent, allowing the client to forget it. The definition of permanent will depend on the possible consequences of client forgetfulness. It would typically range from "information updated on disk" to "information replicated to all sites, and stored to backup media" for important data.

Collaboration

  • Client issues requests to Server via the Request Interface, modifying and resubmitting its request as needed until:
    1. A success response is elicited
    2. A response is lost, and the client is unable to safely repeat its request
    3. The client is unable to make changes required by a Resubmit response
    4. Client policy prevents either changes required by a Resubmit response, or further resubmissions in general

Consequences

The Enqueue pattern creates a mechanism to create a series of new resources on the server side, but the safety and efficacy of the operation is dependent on a specific implementation.

The use of an acceptable types list in a Types Not Understood response means that clients and servers built during different phases of the architecture will generally be able to communicate. Document-based communication has a degree of flexibility built in with must-ignore parameters. The acceptable types list fills a gap when incompatible changes occur to the set of document types, for example a new type deprecates an old type such as atom depreciating rss for news feed syndication.

An explicit failure response allows problems in the architecture to be reported and repaired as required. The resubmit feature allows temporary or permanent changes to the architecture to be accommodated by components without explicit reconfiguration, simplifying management. Note, however, the potential security implications of allowing one component to reconfigure others. A predefined policy for which modifications are permitted and which are to be treated as failure cases can be useful in security-sensitive environments. Incorrect reconfiguration of Create requests can lead to the client issuing incorrect requests to other Servers, so policy should generally be tighter than that enforced for GET requests.

A client that has a series of resources it wants to create should generally face no impediment to sending the requests in parallel. However, this depends on the specifics of the resources being created. This pattern can be misused to produce a general messaging passing escape valve from the normal application of REST patterns. In such cases, in-order processing of requests may be required.

A naive implementation of this pattern using POST does not produce reliable results when the response to a Create request is lost. The create may or may not have gone through, and the client is not able to distinguish between the two cases. PUT is used below as the preferred alternative.

CONNECT may be used to tunnel through intermediaries if ordered processing of requests is required, producing reliable communications within the lifetime of the tunnelled connection.

Implementation

Enqueue can be implemented with HTTP using the following mappings:

Create(base url, document, type)
POST base url+globally unique identifier HTTP/1.1
Content-Type: type
Expect: 100-continue

document

A POST request may be used for Create, however this does not result in reliable behaviour when the response is lost. Using PUT allows the request to be safely repeated.

Success(location url)
Before reading document:
HTTP/1.1 100 Continue
After reading and processing document:
HTTP/1.1 200 OK

Note that 100 Continue handling is optional

All 2xx series response codes can be treated as Success responses for PUT. The location url is the one generate as part of the PUT request.

If POST was used as the Create method, the location url is returned in the response's Location header.

Type Not Understood()
HTTP/1.1 415 Unsupported Media Type
Accept: weighted acceptable types list
Fail(reason)
HTTP/1.1 400 Bad Request

reason

Unknown 1xx series response codes can be treated as a Fail for Create. 3xx series codes that are not understood should be treated as Fail. 4xx series response codes are Fail, except for 401 Unauthorised and 407 Proxy Authentication Required. These are Resubmit responses and should only be treated as failures if they are not understood. 404 Not Found and 410 Gone are excluded from the failed codes list for DELETE requests, as they may be returned as the result of a duplicate request that has already succeeded. 5xx series responses should be treated as Fail, except for 503 Service Unavailable and 504 Gateway Timeout. These are Resubmit and Response Lost responses, respectively.

Resubmit(required changes)

Any of: 301 Moved Permanently, 302 Found, 303 See Other, 305 Use Proxy, 307 Temporary Redirect, 401 Unauthorized, or 407 Proxy Authentication Required.

Response Lost()

Any loss of communication before a response is received. This may include application or TCP/IP level timeouts, or an explicitly terminated connection. The 504 Gateway Timeout response is also equivalent to Response Lost, and indicates a loss occurred somewhere past the TCP connection made directly by the client.

Sample Code

Request request;
request.url="http://example.com/publication-date/first-edition"
information = date(2008-07-05)
request.document_and_type = information.default_encode()

try_again:
switch (request())
{
Success(location url):
	// Save away the location url for further PUT and DELETE requests.
	// A GET to this URL may reveal additional metadata and links.

Type Not Understood(weighted acceptable types list):
	// Re-encode information in an acceptable form
	request.document_and_type =
		information.encode(
			weighted acceptable types list
			)
	jump try_again;

Fail(reason):
	log(reason)

Resubmit(required_changes):
	if policy(request, required_changes)
		request.modify(required_changes)
		jump try_again;
	else
		log("Policy forbids request modification");

Response Lost():
	if request.is_idempotent()
		if policy(request, no required changes)
			jump try_again;
		else
			log("Too many retries");
	else
		log("Response lost - Human intervention required");
}

Known Uses

POST is widely used to create state on the web by submitting form data to servers. Having a human at the console mitigates some of the risks inherent in the possibility of losing responses to the Create request.

Related Patterns