Distributed State Machines
State machines are a fundamental concept in computer science. The concept is simple: sequentially feed a series of inputs, in a particular order, to a black box in order to obtain a desired result.
One way to view this is by focusing on the series of
messages. Consider a typical ftp session: open
,
user
, passwd
, chdir
,
get
, close
. In this world view,
“state” is the hidden, encapsulated, abstraction of
everything that is inside that black box. It is the input and
output messages that are important.
If you look at mechanisms like JAX-RPC, messages too get abstracted away into operations/method calls. While certainly a convenience, this convenience sometimes comes at a price.
From an architect’s point of view, a system is composed of a number of boxes. Sometimes multiple logical boxes will be put on a single physical box. Sometimes a single logical box may span multiple physical boxes. But what is comparatively rare is for a logical box to be composed of fractal portions of a several different physical boxes.
In other words, the network is generally not an irrelevant detail to be abstracted away. See also The Eight Fallacies of Distributed Computing.
Making State Explicit
There is another way to rearrange these pieces that make the overall system more robust and less brittle. Instead of abstracting away the state, expose it.
From Roy Fieldings’s doctoral dissertation, hypermedia is the engine of application state. Each page on the web represents a single state of a single resource. You can obtain that state in a uniform manner (via GET). The data you receive contains hypertext “links” to other resources. By walking the links you traverse the state machine.
Instead of concepts like a “current working directory” being a shared concept between client and server, with all the attendant lifecycle, synchronization, and error recover concerns that managing such a state implies, state becomes explicit and part of every request.
Characteristics you often find of such applications are shared-nothing architectures where there are no long running server processes beyond whatever database you are using; and a preference for fewer, relatively coarse grained messages as opposed to designs that require clients to pelt the server with a comparatively larger number of smaller requests.
Authentication still needs to be orthogonal, and the HTTP solutions are more motivated by pragmatism than theory. “https” is a second URI scheme that is overlaid over the same “http” namespace - something that a number of theorists are uncomfortable with. Basic and digest security are based on challenge/response, and also surface through the abstraction that is an HTTP GET.
To be clear, Roy’s thesis does not put this forward as a panacea or a silver bullet. But for an amazing range of applications to which this technique applies, the result is servers that are much more scalable due to the fact they no longer need to manage state. As an added bonus, clients can safely store away Uniform Resource Identifiers for later use, and even share them with friends via IM or by placing them on business cards and billboards.
Applications
Given the focus on GET, there is one point that often confuses a
number of people. Roy Fielding stated it this way
There’s no
basis for “everything must use GET” in Web
architecture. There is for “use an URI for everything
that’s important”. In particular, one should
not use GET for operations such as
TrackBack or
CartModify. The resource being operated in those cases
are a weblog entry and a cart respectively. The URI should
identify the resource. The HTTP method in both such cases
should be POST
, not GET
.
The core set of verbs defined by HTTP are GET
,
POST
, PUT
, and DELETE
.
These cover the needs of a wide range of distributed
applications. If you find you need more, HTTP is extensible,
but it would make sense to look first to
WebDAV as they may already
have standardized (or be standardizing) the method that you
need. Subversion
and
Microsoft office are examples of applications that use WebDAV
today.