-
-
Save steveklabnik/1478637 to your computer and use it in GitHub Desktop.
Shallow vs. deep representations in XHTML Hypermedia APIs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<body> | |
<!-- the following div is a sample representation of a 'car' domain object; it can be identified as | |
such by the presence of 'car' in its @class. In this case, the car has two attributes, a make | |
and a model, and both are included right here. This is what I call a deep/complete/concrete | |
representation. --> | |
<div id="car123" class="car"> | |
<span class="make">Ford</span> | |
<span class="model">Mustang</span> | |
</div> | |
<!-- The following car doesn't have a make or model here, but it *does* have a self-link. I would | |
call this a shallow representation of the car. For this car, if I want to know the make or | |
model, I can follow the self-link to a different representation of this car and look for it | |
there. Note that this may result in following an arbitrarily long chain of self-links. --> | |
<div id="car234" class="car"> | |
<a rel="self" href="http://example.com/car234"/> | |
</div> | |
<!-- The following car has a make inlined, but no model. I call this a partial representation. If | |
a client wants to know the make of the car, it's here, but if the client wants to know the | |
model, it must then follow the self-link and look for it (or another self-link) there. I | |
stick with the server convention that you can only provide partial representations (including | |
fully shallow ones) if you provide this self-link. --> | |
<div id="car345" class="car"> | |
<a rel="self" href="http://example.com/car345"/> | |
<span class="make">Chevy</span> | |
</div> | |
<p> | |
When implementing a domain client, this means I can have a Car class whose constructor takes a | |
parsed XHTML element like one of the divs above. An enclosing class need only find an element | |
that matches <tt>.//div[@class='car']</tt> and then instantiate a Car with it. | |
</p> | |
<p> | |
In turn, the Car class can implement its getMake and getModel by either finding the data as | |
descendents of the root car div or by locating the self-link and then applying the Proxy pattern | |
to fetch and delegate to another Car instance. | |
</p> | |
<p> | |
Writing clients this way allows servers to vary considerably the granularity of domain object | |
representations without breaking existing clients. This is the style of client I wrote in the | |
demo application I described in my | |
<a href="http://oredev.org/2010/sessions/hypermedia-apis">Hypermedia APIs</a> talk, and is what | |
let that client be forwards-compatible with the various inlining operations I did on the server. | |
</p> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment