TheURLIsNotTheResource,TheResourceIsNotTheThing
When a client sends a request via HTTP to a given URL they are asking for a Representation of a Resource,
not the Resource itself. Unfortunately, the first generation of Web frameworks that tried to implement
practical RESTful architectures often mixed things up and made it seem like the URL was the Resource and
the Resource was the Thing.
To illustrate the distinctions, let's suppose that you want to implement a CRUD (Create, Read, Update,
Delete) interface to an "orders" table in your database. After some discussion, you decide to use a
RESTful API and so you reach for one of the popular tools that purports to make the process simple. The
early stages of the project are promising-- set-up is nearly trivial and in a very short time you have
unit tests demonstrating a working HTTP endpoint for your order data.
But wait, a POST to the "/order" endpoint requires more than a one-to-one relationship with the
database's "order" table. You have to check product availability for each item in the order, you have to
access the "customers" and "customer_addresses" tables to grab the client's address to calculate
shipping, etc. Where does all that extra logic go? Do you cram it into the validation stage? Do you
create different Controller methods to handle those tasks?
Soon, you find that the hands-off "connect the database table to the Web" application you thought you
were building is turning into a series of hacks, work-arounds, and one-offs. The tool that was supposed
to make things easier now actually ties your hands. You're wondering why this all seems so hard and you
begin to suspect that REST is just another in a long line of overcomplicated bondage fads that look great
on paper but fall to pieces under their own complexity when you try to do anything substantial. But the
problem isn't REST-- that's just an architectural style-- the problem is that REST-on-MVC treats the
"orders" table as the Resource and tightly couples the Web API to that physical asset.
DispatchingAlteredStates
In general, an application can be seen as being in (or having) a series of applicationstates. Consider
the typical online registration application. First, the user is presented with an HTML form into which
they type their desired username, password, personal details and other information. We can think of this
as the "prompt state" since the core action involves prompting the user to sign up. Once the user has
filled in the form, they hit the submit button to send the input to a URL on the server that implements
an interface that is able to read that incoming data. Once the request if received, the data is often
verified for fitness-- first by logic on the server side that verifies that the data is complete and
appropriate; then by the user, who is given a read-only HTML page reflecting his or her input for review.
Let's call this the "validation state". Presented with the information they have entered, the user may
choose to return to the prompt state by clicking a "Make Changes" button, or to proceed with registration
by clicking the "Register" button. (Note that the application itself often proactively returns to the
prompt state if it finds the user's input to be unfit). When both the user and the system are satisfied
with the input, the verified data is sent to the server by clicking the "Register" button presented
during the validation state. The server receives the data, creates the new user account, and responds
with an HTML document containing a polite message thanking them for registering. We'll call this the
"complete state".
In short, we can say that the typical user registration application is a single entity that can be in one
or another of three distinct states (prompt, validation, and complete).
---------- -------------- ------------
| Prompt | | Validation | | Complete |
| State |-[User Input]->| State |-[Data Accepted]-->| State |
---------- -------------- ------------
^------[Data Rejected]------|
State Diagram for Online Registration
Despite the fact that this principle of state-based development and design is understood (if only
intuitively) by most experienced Web developers, much of the code running on the Web today remains a mix
of blocks of real application-level programming wrapped by largely redundant application state detection
logic. We have learned through experience the benefits of separating an application's logic from its
presentation, yet we persist in mixing application state detection with code that reacts to those states.
Magpie exists because its developers and users have found that separating application state detection
from behavioral logic offers similar benefits to those that come from drawing a clear line between
application logic and presentation-- namely, the logical division of labor/time, and the ability to
create uncluttered more maintainable code faster, and the freedom to reuse resources by decoupling
distinct aspects of the application implementation.
Magpie works by mapping applicationstates, determined by user input and other factors, to eventhandlermethods, that implement the behavior associated with that state. In Magpie, developers need only register
and implement the specific bits of code that react to a given application state, Magpie makes sure that
correct event (or events) are fired.
Magpie's core distribution provides a simple Web application infrastructure along with a few commonly
useful state-to-event mapping mechanisms that have proven themselves useful over time, but makes no other
presumptions or proscriptions about the design or implementation of a given application. The point is to
reduce brittleness and redundancies while ensuring that developers are free to implement their
application in the way that makes most sense to them.
__END__