entities and actions

2012-02-20 @ 10:24#

those who read my blog know that i favor a hypermedia style when implementing dist-net apps. i don't always use that style (it's not always the proper style for the problem at hand), but when i have the chance to choose which style i implement, hypermedia is often my selection.

so that leads to an obvious question: "why?"

while there are many reasons (too many to cover here), there is one aspect of the hypermedia style that i enjoy very much: it's "action" orientation. not "event-driven" or "behavior-based" but "action" orientation.

problem domains

when working with clients, there is a point (usually early on) where the talk focuses on the "problem domain"; the stuff that must get done. often this information is "bottled up" within the heads of selected members in the client company; sometimes it's well documented in policies & and procedures documents. it can also appear as "source code" from some previous attempt at mapping the problem domain to computer code. this last method of expressing a problem domain is, IME, the least reliable as there have likely been several compromises (to fit the constraints of the coding environment) and often inaccurate translations (due to lack of understanding between the SME [subject matter expert] and the development team/person).

anyway, through some means, the domain is exposed sufficiently to allow the work of mapping that domain onto the selected technology stack. in my case, this is almost always some form of mapping the domain to services running over HTTP. that's what i do most often and, at this point, i rarely get "called" unless the client has "pre-selected" for an HTTP implementation anyway[grin].

so, the next step is how to go about mapping the domain to HTTP. this is not the same as writing code; this is before code. this is the design or architecture part of the experience. and, since it is a design process, there are lots of possibilities, lots of tools, lots of methodologies, etc. and few can be accurately labeled as clearly "right" or "wrong." at this point, this is mostly about the preferences, and proclivities of the architect/designer.

in my recent experience, there are two very common ways to approach this "mapping" task. one that focuses on the entities identified in the problem domain. another that focuses on the actions identified in the problem domain. there are other ways to view the domain (i.e. actors, components, etc.) but i'll focus on these two here: entites and actions.

action orientation

hypermedia designs focus on the actions taking place in the problem domain. things like "get a list of customers sorted by date" and "allow users to filter the order list by sales region" and "allow selected users to add new customers", etc. are all actions. when implementing a system using these actions as the centerpiece, hypermedia designs select the appropriate affordances (within the selected media type) and map those affordances to the identified actions.

for example:

"get a list of customers by date"
<a href="..." rel="customers-by-date">Customers By Date</a>
"allow users to filter the orders list by sales region"
<form action="..." method="get" class="filter-orders">
<input name="region" value=""/>
"allow selected users to add new customers"
<form action="..." method="post" class="add-customer">...</form>

in the above examples, the HTML.A and HTML.FORM affordances are used to provide the actions that map to the problem domain. note that hypermedia style implementations express the problem domain within messages themselves. this is an important point since it makes it possible to share this message in various ways and still retain the problem domain details (i.e. even if the message was sent via FTP, the affordances could still work and still retain their usefulness).

the use of in-message affordances to carry the semantic details of the problem domain (instead of mapping the domain directly to the network protocol) is sometimes cited as a drawback of the hypermedia style.

you'll notice that the actual URIs for each affordance are of little interest here. in the hypermedia style, URIs are treated as nothing more than transient identifiers that enable the actions. hypermedia style implementations are prepared for (and fully expect) the moment when the URI for an affordance changes (for any number of reasons). that is one of the reasons the hypermedia style expresses problem domain details via messages instead of URIs.

entity orientation

entity designs focus on the entities or objects within the problem domain. for example "customers", "orders", etc. are entities. when implementing systems focused on entities, the most common methodology is to create network identities (URIs) that contain the entity names (i.e. http://example.org/customers/, etc.). implementors then use the high-level transfer protocol's network methods as "operators" for each entity.

for example:

"get a list of customers by date"
GET http://example.org/customers?order=date
"allow users to filter the orders list by sales region"
GET http://example.org/orders?region=...
"allow selected users to add new customers"
POST http://example.org/customers/

in the above examples, instead of using a message format to carry the domain semantics, entity oriented designs map the domain directly onto the available protocol and attempt to make URIs themselves carry meaning.

entity orientation is similar to RDF styles where the URI is treated as carrying intrinsic meaning and is the permanent identifier.

the appeal of this direct mapping of a problem domain to a network protocol is fairly obvious. it removes a layer of abstraction which exists for message-based hypermedia style. humans usually have little trouble mapping the limited set of HTTP protocol methods to simple operations on an "entity" (the classic Create, Read, Update, Delete === POST, GET, PUT, DELETE meme). finally, this entity view is easy to support via "tooling" since it essentially reduces distributed network interactions to passing internal objects around using only four possible operations.

but there are limits to this approach. first, entity orientation - while handy - is not how most humans think of life's interactions. usually they think first of the goal they want to achieve and then set up tasks in order to achieve it. second, it turns out to be quite difficult to get everyone to agree on the rules for forming identifiers. the HTTP world has experienced a decade-long dispute over how to handle permantent network identifiers and it still is not sufficently settled.

finally, it happens that many real world cases do not map well to the limited set of HTTP methods. usually there are some suggested compromises on how to handle certain operations within the problem domain (using HTTP.POST to send large search criteria, etc.). WebDAV solved this problem by adding seven additional HTTP methods that fit the targeted problem domain.

a matter of choice

in the end, it all boils down to choices. currently, implementing disitrubted network applications involves mapping the details of a problem domain to existing network standards. there is no getting around that; no choice there! but where we do have a choice is in how we go about accomplishing our task; the styles we use to map the domain to the standards. there are multiple ways to do this. i usually choose the hypermedia style since it tracks well with how i think about distributed networks, matches well with the existing strandards and technologies we use today ( URIs, HTTP, IANA) and presents very few restrictions when implementing clients and servers.

what implementation style do you use? and why do you prefer it?