Skip to content

Instantly share code, notes, and snippets.

@jonm
Created December 8, 2011 02:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jonm/1445773 to your computer and use it in GitHub Desktop.
Save jonm/1445773 to your computer and use it in GitHub Desktop.
Shallow vs. deep representations in XHTML Hypermedia APIs
<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>
@jonm
Copy link
Author

jonm commented Mar 6, 2012

I should note that this representation predates my knowledge of HTML5 microdata, which, being standards-based, is superior to identifying objects and fields using @Class (although technically equivalent). See http://schema.org/ for more details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment