State is everywhere. The world is moving and we need to keep up. We need our computers to help us stay up-to-date with the latest information, chats, trends, stock-prices, news and weather updates, and other important stuff.

The web is primarily a means to move state around. You have some state here, and you want it over there. Or it’s over there, but you want it over here.

For two decades or more, the pre-dominant model for web programming has ignored state, instead requiring developers to work at the level of the HTTP protocol itself.

For example, in Java:

public void handleRequest(HttpServletRequest request, HttpServletResponse response) { response.setStatus( 200 ); }

or in Clojure

( fn [request] { :status 200 })

This programming model puts the HTTP request and response at centre stage. The concept of state is missing entirely - the resource is seen merely as an operation (or set of operations) available for remote invocation.

For years, the same RPC-centered approach has been copied by web frameworks in many languages, old and new (Python, Ruby, Go, Clojure, Rust…​). It has survived because it’s so flexible, as many low-level programming models are.

But there are significant downsides to this model too. HTTP is a big specification, and it’s unreasonable to expect developers to have the time to implement all the relevant pieces of it. What’s more, many developers tend to implement much the same code over and over again, for each and every operation they write.

A notable departure from this programming model can be found in Erlang’s WebMachine and Clojure’s Liberator. To a degree, these libraries ease the burden on the developer by orchestrating the steps required to build a response to a web request. However, developers are still required to understand the state transition diagram underlying this orchestration if they are to successfully exploit these libraries to the maximum extent. Fundamentally, the programming model is the same: the developer is still writing code with a view to forming a response at the protocol level.

While this model has served us well in the past, there are increasingly important reasons why we need an upgrade. Rather than mere playthings, HTTP-based APIs are becoming critical components in virtually every organisation. With supporting infrastructure such as proxies, API gateways and monitoring, there has never been a greater need to improve compatibility through better conformance with HTTP standards. Yet many APIs today at best ignore, and at worst violate many parts of the HTTP standard. For ephemeral prototypes, this casual approach to HTTP is acceptable. Yet HTTP is designed for long-lived systems with lifetimes measured in decades, that must cross departmental and organisational boundaries, while adapting to ongoing changes in technology.