<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6187843820292518013</id><updated>2011-12-08T08:45:16.864+01:00</updated><category term='Client-Side Programming Model'/><category term='Service Types'/><category term='Testing REST Web Services'/><category term='REST Design Mistakes'/><category term='Topic Maps'/><category term='Brainstorm'/><category term='Contracts'/><category term='Yaws'/><category term='NetBeans'/><category term='Separation of Concerns'/><category term='CouchDB'/><category term='Hypermedia Constraint'/><category term='SOAP'/><category term='WAKA'/><category term='Classifying HTTP-based APIs'/><category term='Hypermedia Design'/><category term='Steady-States'/><category term='Glassfish'/><category term='Mac OS X Products'/><category term='UBL'/><category term='Jersey View Client'/><category term='RESTifying Procurement'/><category term='HTTP Howto'/><category term='Jersey'/><category term='REST Frameworks'/><category term='Books'/><category term='Erlang'/><title type='text'>Applying the Web to Enterprise IT</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>75</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-4554078416802758192</id><published>2010-11-19T17:12:00.001+01:00</published><updated>2010-11-19T17:52:23.177+01:00</updated><title type='text'>Generic Media Types Potentially Leak The Model</title><content type='html'>&lt;a href="http://www.moppr.com/"&gt;Jean-Jacques Dubray&lt;/a&gt;&amp;nbsp;just triggered a thought with a comment he made on Twitter regarding the rough ideas to adopt MVC 'ideas' in JAX-RS 2.0. He was worried that an MVC based approach to creating representations exposes the model to the service consumer.&lt;br /&gt;&lt;br /&gt;Interestingly, this is only possible if the service uses generic media types. Specific media types sufficiently limit the kind of information that can be expressed in the representations and prevent the service specific model to be visible to the outside.&lt;br /&gt;&lt;br /&gt;Specific media types enforce the resource boundary and prevent the service's domain model from leaking.&lt;br /&gt;&lt;br /&gt;This is probably a much better argument against application/xml or application/json than the usual reference to the violation of message self descriptiveness.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-4554078416802758192?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/4554078416802758192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/11/generic-media-types-potentially-leak.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4554078416802758192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4554078416802758192'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/11/generic-media-types-potentially-leak.html' title='Generic Media Types Potentially Leak The Model'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-5637332359595945972</id><published>2010-11-15T21:20:00.000+01:00</published><updated>2010-11-15T21:20:16.043+01:00</updated><title type='text'>REST and the Enterprise</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_qvBX_KaH6Bg/TOGV9qu1fBI/AAAAAAAAABc/kMoLCayQxBA/s1600/REST_and_the_Enterprise.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="222" src="http://3.bp.blogspot.com/_qvBX_KaH6Bg/TOGV9qu1fBI/AAAAAAAAABc/kMoLCayQxBA/s320/REST_and_the_Enterprise.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-5637332359595945972?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/5637332359595945972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/11/rest-and-enterprise_15.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5637332359595945972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5637332359595945972'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/11/rest-and-enterprise_15.html' title='REST and the Enterprise'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_qvBX_KaH6Bg/TOGV9qu1fBI/AAAAAAAAABc/kMoLCayQxBA/s72-c/REST_and_the_Enterprise.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6091830158635011421</id><published>2010-11-02T01:27:00.000+01:00</published><updated>2010-11-03T10:54:21.033+01:00</updated><title type='text'></title><content type='html'>"An architectural style called REST (Representational State Transfer) advocates that web applications should use HTTP as it was originally envisioned."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6091830158635011421?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6091830158635011421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/11/architectural-style-called-rest.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6091830158635011421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6091830158635011421'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/11/architectural-style-called-rest.html' title=''/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-4253364945080437713</id><published>2010-10-23T17:00:00.000+02:00</published><updated>2010-11-03T10:54:21.035+01:00</updated><title type='text'>Agency Boundary</title><content type='html'>A central aspect of the problem space that REST is designed for is that the communicating components are typically not owned by a common authority and that therefore change must be enabled to happen without coordinating the change between the authorities. For example, for Amazon it is simply impossible to ask any of its customers whether such and such a change 'would be ok'.&lt;br/&gt;&lt;br/&gt;In my recent &lt;a href="http://www.slideshare.net/algermissen/res-tful-httppatternsantipatterns"&gt;presentation on RESTful HTTP&lt;/a&gt; I used the term 'administrative boundary'. Today, I came across the much better term &lt;em&gt;Agency Boundary&lt;/em&gt; coined by Rohit Khare and Richard N. Taylor in their ICSE'04 paper &lt;a href="http://portal.acm.org/citation.cfm?id=999447"&gt;Extending the REpresentational State Transfer (REST) Architectural Style for Decentralized Systems&lt;/a&gt;:&lt;br/&gt;&lt;br/&gt;&lt;blockquote&gt;An agency boundary denotes the set of components operating on behalf of a common (human) authority, with the power to establish agreement within that set and the right to disagree beyond it it.&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-4253364945080437713?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/4253364945080437713/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/10/agency-boundary.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4253364945080437713'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4253364945080437713'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/10/agency-boundary.html' title='Agency Boundary'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-2590006142728855442</id><published>2010-10-13T01:55:00.000+02:00</published><updated>2010-11-03T10:54:21.037+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Brainstorm'/><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>Interesting Changes *Must* Surface</title><content type='html'>The human brain is truly strange. It happens surprisingly often that you are (well, at least I am) so tied-up in a false assumption that the ability to understand something new is seriously limited.&lt;br/&gt;&lt;br/&gt;Then, when the clouding assumption disappears you have these special, enlightening aha-moments.&lt;br/&gt;&lt;br/&gt;In this particular case I have been thinking a lot about change impact lately. The false assumption I made was that change would ideally be kept hidden and not surface towards the consumers of some provided capability.&lt;br/&gt;&lt;br/&gt;Given that assumption, it seemed strange to maintain a certain RPC criticism I am trying to rationalize: if the goal is to hide change, what is the problem with RPC in the first place?&lt;br/&gt;&lt;br/&gt;Then it dawned some minutes ago: Change to a component is essentially driven by requirements to do new stuff and in order to do new things with a component, the changes &lt;strong&gt;must&lt;/strong&gt; surface. Changes that remain hidden are not worth talking about - these are called implementation details. Details that per definition do not matter at the capability level.&lt;br/&gt;&lt;br/&gt;Now I can joyfully continue working on my RPC criticism: since changes must surface to be interesting we can compare &lt;strong&gt;how&lt;/strong&gt; they can surface in the various architectural styles.&lt;br/&gt;&lt;br/&gt;REST is the only style that requires changes to surface in a way that is guaranteed not to break clients, because REST is rather specific about what can change in which ways. Except for add-on changes (that are not a problem for existing clients) all surfacing changes to a REST server component are bound by the possibilities to vary representations (you may change as long as you do stick to rules of the media type used)&lt;br/&gt;&lt;br/&gt;In RPC-based architectures, change is, you guessed it :-), not constrained at all and might surface in a million ways. Welcome to change impact analysis hell...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-2590006142728855442?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/2590006142728855442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/10/interesting-changes-must-surface.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2590006142728855442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2590006142728855442'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/10/interesting-changes-must-surface.html' title='Interesting Changes *Must* Surface'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-2497291846658433269</id><published>2010-10-12T00:33:00.000+02:00</published><updated>2010-11-03T10:54:21.039+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Contracts'/><title type='text'>Artifact Ownership or When Not to Use REST</title><content type='html'>Here is an indication of situations when applying REST is not appropriate:&lt;br/&gt;When all artifacts that are affected by a possible change are owned by the same project (e.g. stored in the same source code control repository) then REST is not a suitable style.&lt;br/&gt;&lt;br/&gt;An example of this is an application that contains a database component for its private use. Usually the database schema is stored in the repository together with the source code. If you face a need to change one, it is easy to change the other (from a developer coordination point of view).&lt;br/&gt;&lt;br/&gt;The general take away from this is that artifact ownership can be used as an indicator for how appropriate a candidate style is.&lt;br/&gt;&lt;br/&gt;(Consider how much the Unix command line benefits from the uniform API pipe and filter style: Completely decentralized developers can contribute components (grep, awk, sed, less, sort,..) without even engaging into agreeing on how the components talk to each other). The artifacts that make up the unix tool box are maintained by many different parties all over the world.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-2497291846658433269?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/2497291846658433269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/10/artifact-ownership-or-when-not-to-use.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2497291846658433269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2497291846658433269'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/10/artifact-ownership-or-when-not-to-use.html' title='Artifact Ownership or When Not to Use REST'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6212879722768091571</id><published>2010-10-12T00:32:00.000+02:00</published><updated>2010-11-03T10:54:21.041+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Contracts'/><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>Generic vs. Specific Media Types and Evolution</title><content type='html'>In addition to the loss of self-descriptiveness there is another problem with generic media types that is not so obvious. &lt;br/&gt;&lt;br/&gt;Let's think about the problem from the point of view of someone that needs to conduct a change impact analysis. Suppose there is some REST Web service component C, for example an incident management system, that needs to be changed due to some new business requirement. Also suppose the change applies to the resource implementation that allows for retrieval of incident representations. Specifically, the entity needs to be augmented and changed a little.&lt;br/&gt;&lt;br/&gt;&lt;pre lang="http"&gt;&lt;br/&gt;GET /incidents/554&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Content-Type: application/xml&lt;br/&gt;&lt;br/&gt;&lt;incident&gt;&lt;br/&gt;  &lt;!-- whatever happened to what CI --&gt;&lt;br/&gt;&lt;/incident&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;With the generic media type approach above change impact analysis is quite challenging because it is difficult to figure out, which assumptions the consumers actually make about the entity. Thorough change impact analysis would require the change manager to contact the client owners and investigate their assumptions. Based on that information it is then possible to make changes without breaking existing clients.&lt;br/&gt;&lt;br/&gt;&lt;pre lang="http"&gt;&lt;br/&gt;GET /incidents/554&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Content-Type: application/incident&lt;br/&gt;&lt;br/&gt;&lt;incident&gt;&lt;br/&gt;  &lt;!-- whatever happened to what CI --&gt;&lt;br/&gt;&lt;/incident&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;In contrast, when using a specific media type, there is &lt;strong&gt;no need for change impact analysis&lt;/strong&gt; because the media type itself acts as the contract within which the entity can be changed.&lt;br/&gt;&lt;br/&gt;In other words, REST's constraint of specifically typed entities provides for a perimeter within which the server can be flexible without a need to consider the effect the changes have on clients.&lt;br/&gt;&lt;br/&gt;Viewing media types as a perimeter for server side change is an important consideration when designing media types. How big you make the perimeter directly determines the bounds within which the server can later on evolve and, of course, how much burden you put on the client for dealing with entities of that media type.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6212879722768091571?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6212879722768091571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/10/generic-vs-specific-media-types-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6212879722768091571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6212879722768091571'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/10/generic-vs-specific-media-types-and.html' title='Generic vs. Specific Media Types and Evolution'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-2052220680251091234</id><published>2010-10-09T03:56:00.000+02:00</published><updated>2010-11-03T10:54:21.043+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Brainstorm'/><category scheme='http://www.blogger.com/atom/ns#' term='Steady-States'/><title type='text'>Need For User Involvement vs. General Applicability of Media Types</title><content type='html'>The greater the variety of use cases is that a media type can be used to realize the greater is the need for user participation in the implementing application. More steady states are necessary because the user agent cannot differentiate the hypermedia semantics.&lt;br/&gt;&lt;br/&gt;&lt;a href="http://www.nordsc.com/blog/wp-content/uploads/2010/10/diagram.png"&gt;&lt;img src="http://www.nordsc.com/blog/wp-content/uploads/2010/10/diagram-300x233.png" alt="" title="diagram" width="300" height="233" class="aligncenter size-medium wp-image-631" /&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;Media types with more specific hypermedia semantics support more automatic requests on behalf of the user but are less applicable to general use cases.&lt;br/&gt;&lt;br/&gt;In this context it is an interesting observation that HTTP Link headers reduce the need for user involvement while not decreasing the general applicability of the entity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-2052220680251091234?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/2052220680251091234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/10/need-for-user-involvement-vs-general.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2052220680251091234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2052220680251091234'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/10/need-for-user-involvement-vs-general.html' title='Need For User Involvement vs. General Applicability of Media Types'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1338738513339492875</id><published>2010-10-05T14:10:00.000+02:00</published><updated>2010-11-03T10:54:21.045+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing REST Web Services'/><title type='text'>Should we maybe have a TEST method?</title><content type='html'>Just asked myself the question how a service could be put in the position to redirect a test client to a test-version of the URI space it provides?&lt;br/&gt;&lt;br/&gt;What about this:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="HTTP"&gt;&lt;br/&gt;TEST /services/online-shop HTTP/1.1&lt;br/&gt;User-Agent: Simple Tester/1.26&lt;br/&gt;&lt;br/&gt;HTTP/1.1 307 Temporary Redirect&lt;br/&gt;Location: /services/test-online-shop &lt;br/&gt;Content-Type: text/plain&lt;br/&gt;&lt;br/&gt;Please go to /services/test-online-shop to exercise tests on this service.&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Any service that does not understand what it means to provide a testable version of its capabilities, would just respond with a 501 Not Implemented.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1338738513339492875?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1338738513339492875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/10/should-we-maybe-have-test-method.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1338738513339492875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1338738513339492875'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/10/should-we-maybe-have-test-method.html' title='Should we maybe have a TEST method?'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-7139101231136225441</id><published>2010-09-29T23:10:00.000+02:00</published><updated>2010-11-03T10:54:21.046+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Jersey'/><category scheme='http://www.blogger.com/atom/ns#' term='Glassfish'/><category scheme='http://www.blogger.com/atom/ns#' term='Jersey View Client'/><category scheme='http://www.blogger.com/atom/ns#' term='NetBeans'/><title type='text'>NetBeans 6.9.1, GlassFish 3.0.1 and Jersey 1.5</title><content type='html'>&lt;h3&gt;Warning:&lt;/h3&gt;&lt;br/&gt;&lt;hr/&gt;&lt;br/&gt;The procedure described below apparently does &lt;strong&gt;not&lt;/strong&gt; work. I have tried the same thing today (after erasing the .netbeans* directories in my home directory) and there is something missing I think in the 1.4 Jersey library to get this working.&lt;br/&gt;&lt;br/&gt;&lt;hr/&gt;&lt;br/&gt;&lt;br/&gt;Recently, I have picked up the work on the &lt;a href="http://www.nordsc.com/blog/?cat=30"&gt;Jersey View Client&lt;/a&gt; module again. Especially I am interested in combining the JAX-RS server side with Jersey's client side framework.&lt;br/&gt;&lt;br/&gt;Given that I am really positively impressed by Java EE 6 (thanks to &lt;a href="http://adam-bien.com"&gt;Adam Bien&lt;/a&gt; and a bunch of his great presentations) and its integration into NetBeans that natural couple seemed like the way to go.&lt;br/&gt;&lt;br/&gt;Turns out it was a lot harder than I thought!&lt;br/&gt;&lt;br/&gt;The problem with using NetBeans/Java EE 6 for Jersey View Client development is that there is a really tight (and useful) integration between NetBeans, JAX-RS and GlassFish. Given that Jersey 1.5 is ahead of JAX-RS some work has to be done to get rid of the integrated stuff and add the latest, greatest Jersey builds.&lt;br/&gt;&lt;br/&gt;Here is the approach I found to be the least painful:&lt;br/&gt;&lt;br/&gt;&lt;em&gt;(This has been tried with NetBeans 6.9.1, GlassFish 3.0.1 and Jersey 1.5)&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;&lt;h3&gt;Install Netbeans 6.9.1&lt;/h3&gt;&lt;br/&gt;&lt;p&gt;&lt;br/&gt;Download Java Version of Netbeans 6.9.1 from &lt;a href="http://netbeans.org/"&gt;netbeans.org&lt;/a&gt; and install. You skip this of course, if you have NetBeans already. I just want to describe from a defined starting point and actually re-installed mine to walk through the whole thing.&lt;br/&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;h3&gt;Remove GlassFish JAX-RS libraries&lt;/h3&gt;&lt;br/&gt;&lt;p&gt;Remove some libraries distributed with Glassfish as described in 12.2 of &lt;a href="https://jersey.dev.java.net/nonav/documentation/latest/user-guide.html#glassfish"&gt;Jersey User Guide&lt;/a&gt;. The description is not related to NetBeans but the following steps assume you are doing all this inside the GlassFish directory part of your NetBeans installation. For example, /Applications/NetBeans/glassfish-3.0.1/ on my MacBook Pro machine.&lt;br/&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;h3&gt;Download Jersey 1.5 GlashFish-ready Package&lt;/h3&gt;&lt;br/&gt;&lt;p&gt;&lt;br/&gt;Download &lt;a href="http://download.java.net/maven/2/com/sun/jersey/glassfish/v3/jersey-gfv3-core/1.5-SNAPSHOT/jersey-gfv3-core-1.5-SNAPSHOT-project.zip"&gt;Jjersey-gfv3-core-1.5&lt;/a&gt;, unzip and copy JARs into the /glassfish/modules/ directory inside the NetBeans-GlassFish installation.&lt;br/&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;h3&gt;Download Jersey 1.5 View Client Package&lt;/h3&gt;&lt;br/&gt;&lt;p&gt;Download &lt;a href="http://download.java.net/maven/2/com/sun/jersey/experimental/view-client/jersey-view-client/1.5-SNAPSHOT/jersey-view-client-1.5-SNAPSHOT.jar"&gt;Jersey View Client 1.5&lt;/a&gt; and install in that same /glassfish/modules directory.&lt;br/&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;h3&gt;Create a New NetBeans Library for the Jersey JARs&lt;/h3&gt;&lt;br/&gt;&lt;p&gt;From the &lt;em&gt;Tools&lt;/em&gt; menu choose &lt;em&gt;Library&lt;/em&gt; and click on &lt;em&gt;New Library&lt;/em&gt; to create a new library. Name it restlib_jersey15 (or whatever you like).&lt;br/&gt;Add the following JARs to the classpath by selecting them from the NetBeans-GlassFish modules directory where you have previously copied them to:&lt;br/&gt;&lt;/p&gt;&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;&lt;li&gt;jackson-jaxrs.jar&lt;/li&gt;&lt;br/&gt;&lt;li&gt;jersey-core.jar&lt;/li&gt;&lt;br/&gt;&lt;li&gt;jersey-client.jar&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;em&gt;(I am only working on the list now, there are definitely some JARs missing)&lt;/em&gt;&lt;br/&gt;&lt;p&gt;&lt;br/&gt;I tried to keep it to a minimum to only put those JARs in there that you will need for building. The ones necessary at runtime are in GlassFish already anyway. For that reason, you might need to add to restlib_jersey15 if you have compile time dependencies not being resolved.&lt;br/&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;h3&gt;Create Example Application&lt;/h3&gt;&lt;br/&gt;Create new &lt;em&gt;Java Web&lt;/em&gt; - &lt;em&gt;Web Application&lt;/em&gt; project (with dependency-injection-enabled-box checked if you need it).&lt;br/&gt;&lt;br/&gt;In that project, create a new REST resource class: write a class with a method and annotate that with @GET.&lt;br/&gt;&lt;br/&gt;For the compiler to be able to resolve the use of @GET you need to add the library you created above to the project libraries folder (right-click on &lt;em&gt;Libraries&lt;/em&gt; folder and then choose &lt;em&gt;Add Library&lt;/em&gt;. &lt;br/&gt;&lt;br/&gt;During the next build, NetBeans should perform its built-in REST integration magic, asking you about the application's resource path configuration. Use the default action and click &lt;em&gt;OK&lt;/em&gt;.&lt;br/&gt;&lt;br/&gt;The build process triggered by this will pull in some other REST library (I have not been able to figure out where to disable that). Simply remove those and they usually do not get added again.&lt;br/&gt;&lt;br/&gt;Now you are all set to start playing with Jersey Client Views.&lt;br/&gt;&lt;br/&gt;&lt;h3&gt;Notes&lt;/h3&gt;&lt;br/&gt;There is probably more that can be done. Especially there seems to be a way to overwrite the REST-related project properties to directly use the library you created instead of the JAX-RS 1.1. one. However, after one day of trying, I gave up. It seems to be hard wired at some point inside NetBeans. &lt;strong&gt;Any help on this would be greatly appreciated&lt;/strong&gt;.&lt;br/&gt;&lt;br/&gt;If you find I made any mistakes or if it works differently for your setup, please let me know.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-7139101231136225441?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/7139101231136225441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/09/netbeans-691-glassfish-301-and-jersey.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7139101231136225441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7139101231136225441'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/09/netbeans-691-glassfish-301-and-jersey.html' title='NetBeans 6.9.1, GlassFish 3.0.1 and Jersey 1.5'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-3454614601041402509</id><published>2010-09-25T18:28:00.000+02:00</published><updated>2010-11-03T10:54:21.048+01:00</updated><title type='text'></title><content type='html'>Download all of jersey at https://jersey.dev.java.net/svn/jersey/&lt;br/&gt;import into netbeans&lt;br/&gt;open projects&lt;br/&gt;  core&lt;br/&gt;  server&lt;br/&gt;  client&lt;br/&gt;  experimental/view-client&lt;br/&gt;&lt;br/&gt;clean and build explicitly&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-3454614601041402509?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/3454614601041402509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/09/download-all-of-jersey-at-httpsjersey.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3454614601041402509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3454614601041402509'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/09/download-all-of-jersey-at-httpsjersey.html' title=''/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8094776479036137617</id><published>2010-09-01T02:33:00.000+02:00</published><updated>2010-11-03T10:54:21.052+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP Howto'/><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>Spotted Alternates Header in the Wild</title><content type='html'>Just spotted an &lt;a href="http://www.ietf.org/rfc/rfc2295.txt"&gt;Alternates header&lt;/a&gt; in the wild:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="http"&gt;&lt;br/&gt;$ curl http://www.w3.org -HAccept:text/foo -I&lt;br/&gt;&lt;br/&gt;HTTP/1.1 406 Not Acceptable&lt;br/&gt;Date: Tue, 31 Aug 2010 22:26:53 GMT&lt;br/&gt;Server: Apache/2&lt;br/&gt;Alternates: {"Home.html" 1 {type text/html} {charset utf-8} {length 28437}}, {"Home.xhtml" 0.99 {type application/xhtml+xml} {charset utf-8} {length 28437}}&lt;br/&gt;Vary: negotiate,accept&lt;br/&gt;TCN: list&lt;br/&gt;Connection: close&lt;br/&gt;Content-Type: text/html; charset=iso-8859-1&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8094776479036137617?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8094776479036137617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/09/spotted-alternates-header-in-wild.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8094776479036137617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8094776479036137617'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/09/spotted-alternates-header-in-wild.html' title='Spotted Alternates Header in the Wild'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-7362959499501024374</id><published>2010-08-25T01:46:00.000+02:00</published><updated>2010-11-03T10:54:21.054+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Contracts'/><category scheme='http://www.blogger.com/atom/ns#' term='Brainstorm'/><title type='text'>GET /stock-quote/foo vs. getStockQuote("foo")</title><content type='html'>Consider the good old stock quote example from REST vs. RPC discussions. In both variants two kinds of coupling exist.&lt;br/&gt;&lt;br/&gt;On the one hand there is the intentional coupling that causes the client to make the call to &lt;strong&gt;that&lt;/strong&gt; particular remote thing and not just any arbitrary one. The intentional coupling is a human choice, manifested in configuration or code.&lt;br/&gt;&lt;br/&gt;On the other hand there is technical coupling because the client software needs to know (aka be coupled to) the provided interface. Otherwise the communication would no be able to happen.&lt;br/&gt;&lt;br/&gt;Given those two kinds or layers of coupling it makes no sense whatsoever to repeat the specifics already present in the intentional coupling at the technical level by giving &lt;strong&gt;that&lt;/strong&gt; specific remote thing a specific interface.&lt;br/&gt;&lt;br/&gt;Once the intentional choice has been made to talk to &lt;strong&gt;that&lt;/strong&gt; remote thing the interface specifics can be factored away.&lt;br/&gt;&lt;br/&gt;Why design, implement, test, maintain, document and explain more stuff if you can do the same things with less?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-7362959499501024374?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/7362959499501024374/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/08/get-stock-quotefoo-vs-getstockquote.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7362959499501024374'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7362959499501024374'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/08/get-stock-quotefoo-vs-getstockquote.html' title='GET /stock-quote/foo vs. getStockQuote(&amp;quot;foo&amp;quot;)'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6224605261981086634</id><published>2010-08-23T02:10:00.000+02:00</published><updated>2010-11-03T10:54:21.055+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP Howto'/><title type='text'>PUT and Content-Location</title><content type='html'>I noticed some days ago that I totally missed the use of the Content-Location header in responses to PUT requests. Used in this scenario, the client does not need an additional GET to obtain a representation of the resource after the PUT.&lt;br/&gt;&lt;br/&gt;Caches can also cache the response of the PUT in this case.&lt;br/&gt;&lt;br/&gt;&lt;pre lang="http"&gt;&lt;br/&gt;PUT /foo&lt;br/&gt;Content-Type: application/order&lt;br/&gt;&lt;br/&gt;&lt;order&gt;&lt;br/&gt;  &lt;items&gt;...&lt;/items&gt;&lt;br/&gt;&lt;/order&gt;&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Content-Location: /foo&lt;br/&gt;Content-Type: application/order&lt;br/&gt;ETag: "1"&lt;br/&gt;&lt;br/&gt;&lt;order&gt;&lt;br/&gt;  &lt;status&gt;accepted&lt;/status&gt;&lt;br/&gt;  &lt;items&gt;...&lt;/items&gt;&lt;br/&gt;&lt;/order&gt;&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;The Content-Location header is telling the client: "This is the entity and entity headers you would receive for a GET to /foo".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6224605261981086634?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6224605261981086634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/08/put-and-content-location.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6224605261981086634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6224605261981086634'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/08/put-and-content-location.html' title='PUT and Content-Location'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-780149900263442852</id><published>2010-08-16T16:37:00.000+02:00</published><updated>2010-11-03T10:54:21.058+01:00</updated><title type='text'>How much machine do you need?</title><content type='html'>&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-780149900263442852?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/780149900263442852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/08/how-much-machine-do-you-need.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/780149900263442852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/780149900263442852'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/08/how-much-machine-do-you-need.html' title='How much machine do you need?'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6229605632892205239</id><published>2010-08-16T11:42:00.000+02:00</published><updated>2010-11-03T10:54:21.059+01:00</updated><title type='text'>Thoughts on Media Types</title><content type='html'>&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6229605632892205239?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6229605632892205239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/08/thoughts-on-media-types.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6229605632892205239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6229605632892205239'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/08/thoughts-on-media-types.html' title='Thoughts on Media Types'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1280506694778170109</id><published>2010-05-21T00:59:00.000+02:00</published><updated>2010-11-03T10:54:21.060+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Amazingly Close</title><content type='html'>While looking up some stuff in the book &lt;a href="http://msdn.microsoft.com/en-us/library/ff647309.aspx"&gt;"Integration Patterns"&lt;/a&gt; I spotted a tiny sentence that is amazingly close to REST. In chapter one on page 3 the authors (among them &lt;a href="http://eaipatterns.com/ramblings.html"&gt;Gregor Hohpe&lt;/a&gt;, BTW) emphasize that from the point of view of integration the whole must be considered instead of solely designing for each integration between two applications in turn. The sentence is&lt;br/&gt;&lt;blockquote&gt;However, if you approach this same problem from an integration architecture perspective, the ideal application is a thin layer of presentation that consumes shared functionality or data at the enterprise level.&lt;/blockquote&gt;&lt;br/&gt;I find this amazingly close to the notion of a user agent component consuming representations and capabilities provided by resources.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1280506694778170109?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1280506694778170109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/05/amazingly-close.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1280506694778170109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1280506694778170109'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/05/amazingly-close.html' title='Amazingly Close'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-5060001131230910237</id><published>2010-05-12T10:51:00.000+02:00</published><updated>2010-11-03T10:54:21.061+01:00</updated><title type='text'>Serendipitous Reuse vs. Reusable Services</title><content type='html'>The notion of reusable service builds on the anticipation of its uses&lt;br/&gt;&lt;br/&gt;Reusable components notion focusses on using the same component for the same purpose often. There is no focus on use in unanticipated contexts. seren. reuse oth does that.&lt;br/&gt;&lt;br/&gt;Serendipitous reuse on the other hand focusses on building components (that expose functionality) and using those compoents in unanticipated ways.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-5060001131230910237?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/5060001131230910237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/05/serendipitous-reuse-vs-reusable.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5060001131230910237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5060001131230910237'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/05/serendipitous-reuse-vs-reusable.html' title='Serendipitous Reuse vs. Reusable Services'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6671707798361665786</id><published>2010-05-06T11:13:00.000+02:00</published><updated>2010-11-03T10:54:21.063+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client-Side Programming Model'/><category scheme='http://www.blogger.com/atom/ns#' term='Steady-States'/><title type='text'>IRC Conversation on User, User Agent, Media Types, Application etc.</title><content type='html'>Currently I am trying to figure out the significance of the various aspects of a RESTful architecture with regard to modeling. Such aspects as user agent, media type, steady state, user, application, and application state. Tried to build-up an &lt;a href="http://rest.hackyhack.net/2010-05-05.html#404"&gt;explanatory train of thought&lt;/a&gt; on that basis in an exchange with &lt;a href="http://twitter.com/ordnungswidrig"&gt;Philipp Meier&lt;/a&gt; on &lt;a href="http://rest.hackyhack.net/"&gt;#rest IRC&lt;/a&gt; yesterday. It is the typical, hard to read, IRC conversation but you might find it useful nevertheless.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6671707798361665786?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6671707798361665786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/05/irc-conversation-on-user-user-agent.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6671707798361665786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6671707798361665786'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/05/irc-conversation-on-user-user-agent.html' title='IRC Conversation on User, User Agent, Media Types, Application etc.'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-4740346061536542356</id><published>2010-04-30T13:35:00.000+02:00</published><updated>2010-11-03T10:54:21.064+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client-Side Programming Model'/><category scheme='http://www.blogger.com/atom/ns#' term='Jersey'/><category scheme='http://www.blogger.com/atom/ns#' term='Jersey View Client'/><title type='text'>Jersey Client Side: The ViewResource Class</title><content type='html'>The &lt;a href="http://www.nordsc.com/blog/?p=439"&gt;last posting&lt;/a&gt; in this introductory series provided a high level overview of the Jersey client side framework I am working on together with &lt;a href="http://blogs.sun.com/sandoz/"&gt;Paul&lt;/a&gt;. In this one, we look at some of the details.&lt;br/&gt;&lt;br/&gt;At the heart of the framework lies the concept of &lt;em&gt;ViewResources&lt;/em&gt;. Conceptually, ViewResources are an extension of the existing Jersey client side &lt;em&gt;WebResource&lt;/em&gt; class. A &lt;em&gt;ViewResource&lt;/em&gt; is a client side 'handle' for an HTTP resource through which HTTP requests to the resource can be performed. While &lt;em&gt;WebResource&lt;/em&gt; 'invocations' result in &lt;em&gt;ClientResponses&lt;/em&gt; or object representations of the response entities 'invocations' of &lt;em&gt;ViewResources&lt;/em&gt; produce view objects that encapsulate assumptions (including anticipated next transitions).&lt;br/&gt;&lt;br/&gt;The choice of view class for a given request completely expresses the assumptions made about the resource and the response. The view class in turn encapsulates these assumptions in a single artifact.&lt;br/&gt;&lt;br/&gt;Regarding the examples that follow it is important to keep in mind that the view objects are not to be seen as local proxies for remote 'objects' but that the view objects hold application state and provide access to the data contained and a means to activate the controls that are (maybe) embedded in it.&lt;br/&gt;&lt;br/&gt;In a subsequent installment of this introductory series we will see how even the entities of error responses constitute application state and can be used to construct corresponding views (possibly with contained application data and/or embedded controls for outgoing state transitions).&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;GET requests&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;URI poUri = URI.create("http://foo.org/purchaseOrders/42");&lt;br/&gt;ViewResource vr = client.viewResource(poUri);&lt;br/&gt;PurchaseOrderView pov = vr.get(PurchaseOrderView.class);&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;For GET requests there is a shorthand removing the need for an intermediate ViewResource object:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;URI poUri = URI.create("http://foo.org/purchaseOrders/42");&lt;br/&gt;PurchaseOrderView pov = client.view(poUri,PurchaseOrderView.class);&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;PUT requests&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;URI poUri = URI.create("http://foo.org/purchaseOrders/42");&lt;br/&gt;ViewResource vr = client.viewResource(poUri);&lt;br/&gt;PurchaseOrderView pov = vr.put(PurchaseOrderView.class, "some purchase order data");&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;For the use with PUT requests the build method of the PurchaseOrderView class could be implemented to work with both &lt;em&gt;200 Ok&lt;/em&gt; and &lt;em&gt;204 No Content&lt;/em&gt; responses. In the former case the body woud be interpreted as a representation of the order and in the latter the build method could perform an additional GET on the request URI to obtain a a representation of the order. We will discuss such support for automated transitions in a dedicated posting.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;POST requests&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;URI colUri = URI.create("http://foo.org/purchaseOrders");&lt;br/&gt;ViewResource vr = client.viewResource(colUri);&lt;br/&gt;CreatedView&lt;PurchaseOrderView&gt; cv = new CreatedView(PurchaseOrderView.class);&lt;br/&gt;vr.post(cv, "some purchase order data");&lt;br/&gt;PurchaseOrderView newPoView = cv.getCreated();&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;This example makes use of the 'helper' view class &lt;em&gt;CreatedView&amp;lt;T&amp;gt;&lt;/em&gt; provided with the framework. This view class encapsulates the HTTP mechanics related to &lt;em&gt;201 Created&lt;/em&gt; responses and makes the created resource retrievable as a view through the &lt;em&gt;getCreated()&lt;/em&gt; method.&lt;br/&gt;&lt;br/&gt;Note how this example instantiates the view class outside the framework and supplies the instance directly to the &lt;em&gt;post()&lt;/em&gt; invocation.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;DELETE requests&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;URI poUri = URI.create("http://foo.org/purchaseOrders/42");&lt;br/&gt;ViewResource vr = client.viewResource(poUri);&lt;br/&gt;VoidView vv = vr.delete(VoidView.class);&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;This example uses the framework supplied view class &lt;em&gt;VoidView&lt;/em&gt; to handle the (possible empty) response to the DELETE request. Because the VoidView really does not express any kind of expectation its use outside the context of pure examples is rather useless.&lt;br/&gt;&lt;br/&gt;Expectations pertaining to the context of a request should be encapsulated &lt;strong&gt;inside&lt;/strong&gt; a view class and not be propagated into the code that actually uses the view. Deal with HTTP mechanics (such as checking response status) inside view classes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-4740346061536542356?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/4740346061536542356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/04/jersey-client-side-viewresource-class.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4740346061536542356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4740346061536542356'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/04/jersey-client-side-viewresource-class.html' title='Jersey Client Side: The ViewResource Class'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1418974276354380152</id><published>2010-04-29T16:24:00.000+02:00</published><updated>2010-11-03T10:54:21.066+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Client-Side Programming Model'/><category scheme='http://www.blogger.com/atom/ns#' term='Jersey'/><category scheme='http://www.blogger.com/atom/ns#' term='Jersey View Client'/><title type='text'>A RESTful Client Side Framework for Jersey</title><content type='html'>For the past couple of weeks &lt;a href="http://blogs.sun.com/sandoz/"&gt;Paul Sandoz&lt;/a&gt; and I have been working on a client side framework for Jersey that encourages RESTful design on the client side. After a trial period with frequent code changes, we feel that the code base is now stable enough to go public.&lt;br/&gt;&lt;br/&gt;The framework introduces an annotation based approach that enables developers to turn arbitrary classes of the client side code into HTTP response handlers. The framework refers to instances of such classes as 'views' (mostly for the lack of a better term). &lt;br/&gt;&lt;br/&gt;Views serve three purposes:&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;1. Build-up state corresponding to the handled response&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;View classes provide specifically annotated methods that will be invoked by the framework core to handle the response. These 'build' methods are intended to build-up the state of the view object from the HTTP response.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;2. Present or make accessible the data of the current application state&lt;/strong&gt;&lt;br/&gt;Usually, users (human or machine) intend to use the information contained in HTTP response bodies. View objects make this information accessible either through GUI elements for human users or through access methods for machine users.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;3. Use the hypermedia controls embedded in the response body to turn user (human or machine) actions into HTTP requests.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Both human and machine users interact with RESTful applications through user agent components by activating the controls embedded in the representations of the current application state. View objects provide a means for the user to activate the controls and will then create the corresponding HTTP requests. The means for control activation can be GUI elements in the case of human users or regular methods in the case of machine users.&lt;br/&gt;&lt;br/&gt;Enough theory - let's look at some code.&lt;br/&gt;&lt;br/&gt;Suppose we want to develop a view class that is is suitable for Atom Publishing Protocol collections. The following examples step by step show the different aspects of such a view class and how it could be used.&lt;br/&gt;&lt;br/&gt;First, we need a build method for handling HTTP success responses to GET requests to collection resources.&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;public class CollectionView {&lt;br/&gt;&lt;br/&gt;	private Feed feed;&lt;br/&gt;&lt;br/&gt;	@GET&lt;br/&gt;	@Status(200)&lt;br/&gt;	@Consumes("application/atom+xml")&lt;br/&gt;	public void build(Feed feed) {&lt;br/&gt;		this.feed = feed;&lt;br/&gt;	}&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;The annotations on the build-method indicate to the framework core that the method applies to responses to GET requests that have a status of &lt;em&gt;200 Ok&lt;/em&gt; and a response body of the media type &lt;em&gt;application/atom+xml&lt;/em&gt;. As requested by the method parameter list the framework core will inject the response body as a Feed object to enable access to the body inside the build method.&lt;br/&gt;&lt;br/&gt;The code below shows how the &lt;em&gt;CollectionView&lt;/em&gt; class might be used. The new view method on the Jersey &lt;em&gt;Client&lt;/em&gt; class performs an HTTP GET on the provided URI, instantiates a new object of the provided class and then dispatches to a suitable build method of the created instances (based on the annotations).&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;public void main(String args[]) {&lt;br/&gt;	URI uri = URI.create("http://example.org/blogs/jim/entries");&lt;br/&gt;	Client client = new Client();&lt;br/&gt;	&lt;br/&gt;	CollectionView cv = client.view(uri, CollectionView.class);&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Next we need to add to our &lt;em&gt;CollectionView&lt;/em&gt; class methods that provide access to information contained in the feed. To keep things simple, we'll just provide a getter for the title of the feed.&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;public class CollectionView {&lt;br/&gt;&lt;br/&gt;	private Feed feed;&lt;br/&gt;&lt;br/&gt;	@GET&lt;br/&gt;	@Status(200)&lt;br/&gt;	@Consumes("application/atom+xml")&lt;br/&gt;	public void build(Feed feed) {&lt;br/&gt;		this.feed = feed;&lt;br/&gt;	}&lt;br/&gt;&lt;br/&gt;	public String getFeedTitle() {&lt;br/&gt;		return this.feed.getTitle();&lt;br/&gt;	}&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Example for using the &lt;em&gt;getFeedTitle()&lt;/em&gt; method:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;public void main(String args[]) {&lt;br/&gt;	URI uri = URI.create("http://example.org/blogs/jim/entries");&lt;br/&gt;	Client client = new Client();&lt;br/&gt;	&lt;br/&gt;	CollectionView cv = client.view(uri, CollectionView.class);&lt;br/&gt;	System.out.println("Feed title is " + cv.getFeedTitle());&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;The third purpose of view classes mentioned above is to provide users (human or machine) with a means to activate the controls embedded in the response entities. &lt;a href="http://tools.ietf.org/html/rfc5005"&gt;RFC 5005&lt;/a&gt; defines (among others) the 'next' link relation that can be used to tell a consumer of the feed document where the next page of the feed representation is located. We will use this link relation to demonstrate how a view class can expose a hypermedia control to the user.&lt;br/&gt;&lt;br/&gt;One possibility to make 'next' links accessible to the user is to provide some &lt;em&gt;getNextPageUri()&lt;/em&gt; method on the view class that can be called by the user to retrieve the URI of the next page. However, we can also provide a design that matches better the usual intent of the user of a feed: to iterate over the contained entries.&lt;br/&gt;&lt;br/&gt;The code below shows an &lt;em&gt;iterateEntries()&lt;/em&gt; method that processes all entries in the feed document of the view and follows any 'next' link to subsequent feed pages. The &lt;em&gt;EntryHandler&lt;/em&gt; interface acts as a callback class.&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;public interface EntryHandler {&lt;br/&gt;&lt;br/&gt;	public boolean handleEntry(Entry e);&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;public class CollectionView {&lt;br/&gt;&lt;br/&gt;	private Client client;&lt;br/&gt;	private Feed feed;&lt;br/&gt;&lt;br/&gt;	@GET&lt;br/&gt;	@Status(200)&lt;br/&gt;	@Consumes("application/atom+xml")&lt;br/&gt;	public void build(Feed feed, @Context Client client) {&lt;br/&gt;		this.client = client;&lt;br/&gt;		this.feed = feed;&lt;br/&gt;	}&lt;br/&gt;&lt;br/&gt;	public String getFeedTitle() {&lt;br/&gt;		return this.feed.getTitle();&lt;br/&gt;	}&lt;br/&gt;&lt;br/&gt;	public void iterateEntries(EntryHandler entryHandler) {&lt;br/&gt;&lt;br/&gt;		List&lt;Entry&gt; entries = this.feed.getEntries();&lt;br/&gt;		for (Entry entry : entries) {&lt;br/&gt;			boolean proceed = entryHandler.handleEntry(entry);&lt;br/&gt;			if (!proceed) {&lt;br/&gt;				return;&lt;br/&gt;			}&lt;br/&gt;		}&lt;br/&gt;&lt;br/&gt;		Link link = this.feed.getLink("next");&lt;br/&gt;		if (link == null) {&lt;br/&gt;			return;&lt;br/&gt;		}&lt;br/&gt;		&lt;br/&gt;		URI nextUri = link.getHref().toURI();&lt;br/&gt;		CollectionView v = this.client.view(nextUri, CollectionView.class);&lt;br/&gt;&lt;br/&gt;		v.iterateEntries(entryHandler);&lt;br/&gt;	}&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;Note that we have added an annotated parameter to the build method to inject the client:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;public void build(Feed feed, @Context Client client) { &lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt; This is necessary because the &lt;em&gt;iterateEntries()&lt;/em&gt; method constructs a view for the next page if a 'next'-link is found.&lt;br/&gt;&lt;br/&gt;The &lt;em&gt;CollectionView&lt;/em&gt; class can now be used to iterate over all entries in a feed as follows:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="java"&gt;&lt;br/&gt;public void main(String args[]) {&lt;br/&gt;	URI uri = URI.create("http://example.org/blogs/jim/entries");&lt;br/&gt;	Client client = new Client();&lt;br/&gt;	&lt;br/&gt;	CollectionView cv = client.view(uri, CollectionView.class);&lt;br/&gt;&lt;br/&gt;	 cv.iterateEntries(new EntryHandler() {&lt;br/&gt;&lt;br/&gt;		private int count = 0;&lt;br/&gt;&lt;br/&gt;		public boolean handleEntry(Entry entry) {&lt;br/&gt;			this.count++;&lt;br/&gt;			System.out.println("Entry #" + this.count + ": " + entry.getTitle());&lt;br/&gt;&lt;br/&gt;			// limit the number of processed entries to 200&lt;br/&gt;			return (this.count &lt;= 200);&lt;br/&gt;		}&lt;br/&gt;	});&lt;br/&gt;&lt;br/&gt;}&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;(You can find a similar example in the Jersey sources at &lt;em&gt;experimental/view-client/jersey-view-client-samples/atompub-simple-view-client-sample&lt;/em&gt;)&lt;br/&gt;&lt;br/&gt;The &lt;em&gt;CollectionView&lt;/em&gt; example class demonstrates the three purposes of a view:&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;Handle HTTP responses&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Present or make accessible application state&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Provide a means for the user to activate hypermedia controls&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;br/&gt;Interactions with resources never occur without assumptions about the resources (for example that it is a Web page, an image or an Atom Publishing Protocol collection). View classes are manifestations of such assumptions and the choice of a specific view class for a given interaction expresses which assumptions are being made.&lt;br/&gt;&lt;br/&gt;From a code structuring and maintenance perspective view classes nicely bundle up all the elements that pertain to such assumptions and act as a single point of documentation. &lt;br/&gt; &lt;br/&gt;There are a number of issues we have not covered in this first blog. Among them are&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;Support for several response body media types&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Error handling&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Constructing requests other than GET&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Performing a sequence of automated requests&lt;/li&gt;&lt;br/&gt;        &lt;li&gt;Using 'existing' client side classes as view classes&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;br/&gt;We will talk about those and other features in follow up postings.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Instructions for Obtaining the Code&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Unfortunately there are currently issues obtaining the latest SNAPSHOT artifacts from the java.net maven repository. Until this is resolved it is necessary to obtain and build Jersey yourself. The new client side framework is located in &lt;em&gt;experimental/view-client&lt;/em&gt;.&lt;br/&gt;&lt;br/&gt;Use SE 6 with maven version 2.2.0 or 2.2.1.&lt;br/&gt;&lt;br/&gt;Join the Jersey project as an Observer at https://jersey.dev.java.net.&lt;br/&gt;&lt;br/&gt;Check out the trunk source:&lt;br/&gt;&lt;br/&gt; &lt;code&gt;&lt;br/&gt;svn checkout \&lt;br/&gt;https://jersey.dev.java.net/svn/jersey/trunk/jersey \&lt;br/&gt;jersey --username &amp;lt;username&amp;gt;&lt;br/&gt;&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;Clean and install:&lt;br/&gt;&lt;br/&gt;&lt;code&gt;mvn clean install&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;If you want to do this a bit quicker you can skip the tests&lt;br/&gt;&lt;br/&gt; &lt;code&gt;mvn -Dmaven.test.skip=true clean install&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;You may need to set the following maven options (which can be set using the MAVEN_OPTS environment variable):&lt;br/&gt;&lt;br/&gt; &lt;code&gt;-Xmx1048m -XX:PermSize=64M -XX:MaxPermSize=128M&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Discussion&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Please send comments to the &lt;a href="https://jersey.dev.java.net/servlets/SummarizeList?listName=users"&gt;jersey users list&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1418974276354380152?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1418974276354380152/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/04/restful-client-side-framework-for.html#comment-form' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1418974276354380152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1418974276354380152'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/04/restful-client-side-framework-for.html' title='A RESTful Client Side Framework for Jersey'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-7455782461689121012</id><published>2010-04-04T20:29:00.000+02:00</published><updated>2010-11-03T10:54:21.069+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Steady-States'/><title type='text'>Steady-State</title><content type='html'>I have been meaning to write up for some time something about the notion of steady state. Now it ended up in a &lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/15109"&gt;rest-duscuss posting&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Some references that I found insightful:&lt;br/&gt;&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;&lt;li&gt;&lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_3_3"&gt;Steady-State in Roy's dissertation&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/12101"&gt;Posting dealing with application entry points&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/12180"&gt;Web applications can have many entry points&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/5841"&gt;Steady-states are to be understood in isolation&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/13606"&gt;Steady-State, bookmarks, cool URIs&lt;/a&gt;(last two paragraphs)&lt;br/&gt;&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;br/&gt;Slightly related from this blog: &lt;a href="http://www.nordsc.com/blog/?p=152"&gt;In Fear of Sub Requests&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-7455782461689121012?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/7455782461689121012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/04/steady-state.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7455782461689121012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7455782461689121012'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/04/steady-state.html' title='Steady-State'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6658144666538127240</id><published>2010-03-31T14:25:00.000+02:00</published><updated>2010-11-03T10:54:21.070+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST Design Mistakes'/><title type='text'>Why 'Action Resources' are a REST Anti Pattern</title><content type='html'>REST's uniform interface constraint requires the operations that can be invoked on a resource to be generic, meaning that the applicability of an operation must not depend on the actual nature of the target resource. The uniform interface does not prohibit additional methods to be defined but requires any extension method to be generic. &lt;a href="http://tools.ietf.org/html/rfc5789"&gt;PATCH&lt;/a&gt; or &lt;a href="http://gbiv.com/protocols/waka/200211_fielding_apachecon.ppt"&gt;MONITOR&lt;/a&gt; (slide 16) for example are valid extensions, while ORDER or PAY are not.&lt;br/&gt;&lt;br/&gt;Our OO-biased brains are trained to think in terms of classes and associated operations (Cart.order()) and it apparently takes a considerable amount of time for our brains to re-wire and think in terms of transferring representations to modify resource state.&lt;br/&gt;&lt;br/&gt;As a result, people are tempted to come up with ways to map non-uniform operations onto HTTP's uniform interface. One offspring of such endeavor is the REST anti pattern of &lt;em&gt;Action Resources&lt;/em&gt;.&lt;br/&gt;&lt;br/&gt;I have not tracked it back to its origin, but the general form goes something like this:&lt;br/&gt;&lt;br/&gt;Given an operation foo(), define a link semantic 'foo' that enables the server to tell the client what the URI is of 'the foo-action resource of some other resource R. Knowing the foo-action resource R&lt;sub&gt;foo&lt;/sub&gt;, the client would then be able to invoke the foo() operation on R by means of an empty POST to R&lt;sub&gt;foo&lt;/sub&gt;:&lt;br/&gt;&lt;br/&gt;Find foo-action resource of R:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="http"&gt;&lt;br/&gt;HEAD /items/56&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Link: &lt;/items/56/foo&gt;;rel=foo&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Invoke foo() on R:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="http"&gt;&lt;br/&gt;POST /items/56/foo&lt;br/&gt;Content-Length: 0&lt;br/&gt;&lt;br/&gt;204 No Content&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;So, why am I calling it an &lt;em&gt;&lt;strong&gt;anti&lt;/strong&gt; pattern&lt;/em&gt;?&lt;br/&gt;&lt;br/&gt;Action resources are an anti pattern because the approach violates REST's self descriptive messages constraint. How so? Because the meaning of the POST request depends on resource state at the time the client learned that /items/56/foo is the foo-action resource of /items/56. There is nothing in the request that allows the server to understand the actual intention of the client at the time the server handles the POST request.&lt;br/&gt;&lt;br/&gt;Suppose the client issues the above HEAD request at time T&lt;sub&gt;1&lt;/sub&gt;, the server replies at T&lt;sub&gt;2&lt;/sub&gt; and the client receives the response at T&lt;sub&gt;3&lt;/sub&gt;. By the time T&lt;sub&gt;4&lt;/sub&gt; the client sends the POST request to the action resource (and T&lt;sub&gt;5&lt;/sub&gt; when the server actually receives it) the server might have changed and is now looking at the POST with the empty body which translates to the client intention of telling the resource /items/56/foo to process this [empty body].&lt;br/&gt;&lt;br/&gt;The server does not know that the request semantics depend on the server state at T&lt;sub&gt;2&lt;/sub&gt; when the server created the HEAD response and therefore cannot detect any mismatch between client intention and its own interpretation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6658144666538127240?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6658144666538127240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/03/why-resources-are-rest-anti-pattern.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6658144666538127240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6658144666538127240'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/03/why-resources-are-rest-anti-pattern.html' title='Why &amp;#39;Action Resources&amp;#39; are a REST Anti Pattern'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8633901876960630022</id><published>2010-03-07T15:31:00.000+01:00</published><updated>2010-11-03T10:54:21.072+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP Howto'/><title type='text'>DELETE and 201 Created</title><content type='html'>Just thought about a useful combination of DELETE and a 201 Created response:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="http"&gt;&lt;br/&gt;DELETE /service/documents/667&lt;br/&gt;&lt;br/&gt;201 Created&lt;br/&gt;Location: /service/archive/documents/667&lt;br/&gt;Content-Type: text/plain&lt;br/&gt;&lt;br/&gt;Document /service/documents/667 has been deleted&lt;br/&gt;and archived at /service/archive/documents/667.&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8633901876960630022?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8633901876960630022/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/03/delete-and-201-created.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8633901876960630022'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8633901876960630022'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/03/delete-and-201-created.html' title='DELETE and 201 Created'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-4074801042403679683</id><published>2010-03-02T15:41:00.000+01:00</published><updated>2010-11-03T10:54:21.074+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RESTifying Procurement'/><title type='text'>The Farmer in the Dell</title><content type='html'>A couple of minutes ago, &lt;a href="http://djangopeople.net/bhaugen/"&gt;Bob Haugen&lt;/a&gt; posted a &lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/14954"&gt;question&lt;/a&gt; on the &lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/"&gt;rest-discuss&lt;/a&gt; list that essentially comes down to the question of how the use of REST affects a classic 2PC scenario. Note that the question is not &lt;strong&gt;how&lt;/strong&gt; you do 2PC with REST but what the implications are regarding compensation strategies etc.&lt;br/&gt;&lt;br/&gt;The scenarios is this: There are N farmers that each have an amount of X&lt;sub&gt;n&lt;/sub&gt; pints of berries to sell. The farmers tell M market places about their amount and K buyers order berries from the market places. The 2PC issues come in when orders to different market places overlap and more berries are ordered from a farmer than he has available.&lt;br/&gt;&lt;br/&gt;I tink this relates very nicely to my &lt;a href="http://www.nordsc.com/blog/?cat=13"&gt;RESTifying Procurement&lt;/a&gt; endeavor and I therefore plan to make the scenario the overall target to which my experiment should evolve.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-4074801042403679683?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/4074801042403679683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/03/farmer-in-dell.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4074801042403679683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4074801042403679683'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/03/farmer-in-dell.html' title='The Farmer in the Dell'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-9126122578286133278</id><published>2010-02-27T18:16:00.000+01:00</published><updated>2010-11-03T10:54:21.075+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Classifying HTTP-based APIs'/><category scheme='http://www.blogger.com/atom/ns#' term='WAKA'/><category scheme='http://www.blogger.com/atom/ns#' term='CouchDB'/><title type='text'>Classifying the CouchDB API</title><content type='html'>In the context of my &lt;a href="http://nordsc.com/ext/classification_of_http_based_apis.html"&gt;Classification of HTTP-based APIs&lt;/a&gt; &lt;a href="https://twitter.com/hanonymity"&gt;@hanonymity&lt;/a&gt; today asked me, how I would classify the CouchDB API.&lt;br/&gt;&lt;br/&gt;Ok, let's see. Going to the &lt;a href="http://wiki.apache.org/couchdb/HTTP_Document_API"&gt;HTTP Document API&lt;/a&gt; immediately reveals that the API definitely violates the &lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_3_3"&gt;hypermedia constraint&lt;/a&gt; (see last paragraph) because there is an API documentation in the first place. The only thing one would expect to see for a RESTful API is a set of media type specifications along the lines "The CouchDB API uses the following media types and link relations....which are specified here...".&lt;br/&gt;&lt;br/&gt;Next, let's check if the API can be classified as &lt;a href="http://nordsc.com/ext/classification_of_http_based_apis.html#http-type-two"&gt;HTTP-based Type II&lt;/a&gt;. The fastest way to verify this is usually to look for the use of only specified media types and it is immediately obvious that the CouchDB uses the generic media type application/json and not a specific one that would make the messages self-descriptive. CouchDB API fails the test for &lt;i&gt;HTTP-based Type II&lt;/i&gt;, too.&lt;br/&gt;&lt;br/&gt;This leaves us with the question whether the API is &lt;a href="http://nordsc.com/ext/classification_of_http_based_apis.html#http-type-one"&gt;HTTP-based Type I&lt;/a&gt; or if we have to let go all hope because it must be classified as &lt;a href="http://nordsc.com/ext/classification_of_http_based_apis.html#uri-rpc"&gt;RPC URI-Tunneling&lt;/a&gt;. The thing to look out for is of course the use of action names in URIs. It does not take a lot of browsing through the API documentation to reveal that the CouchDB API designers knew what they were doing. The API very thoroughly leverages HTTP mechanics and we can happily conclude that the API is an &lt;i&gt;HTTP-based Type I&lt;/i&gt; API.&lt;br/&gt;&lt;br/&gt;Is it a problem that the CouchDB API violates two out of four of REST's interface constraints and is therefore not REST at all? I do not think so, because I would not consider achieving loose coupling between a database (backend) and the component that uses the database to be a very useful goal. At least not at the cost that you have to pay on the client side and also because there is strong coupling around the schema anyway between a database and the code that is using it.&lt;br/&gt;&lt;br/&gt;However, I think CouchDB API shows quite nicely how an API can still benefit from the simplicity induced by &lt;i&gt;HTTP-based Type I&lt;/i&gt; even if we cannot label the API as REST.&lt;br/&gt;&lt;br/&gt;A note on the COPY method: It would be helpful to say in the API documentation that the COPY extension method is actually WebDAV's COPY method. And while we are at it, it makes also sense to note that COPY does not really fit HTTP because COPY is a method that works on two resources (Source and Destination) while HTTP does not support such method semantics. For example, caches would not understand that they need to flush the representations of the (now overwritten) destination resource.&lt;br/&gt;&lt;br/&gt;This is not a question of RESTfulness though. It would be entirely possible to design &lt;a href="http://en.wikipedia.org/wiki/Waka_(protocol)"&gt;an architecture that adheres to the REST style and provides methods that work on two resources&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-9126122578286133278?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/9126122578286133278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/classifying-couchdb-api.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/9126122578286133278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/9126122578286133278'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/classifying-couchdb-api.html' title='Classifying the CouchDB API'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-788454429352835081</id><published>2010-02-25T11:02:00.000+01:00</published><updated>2010-11-03T10:54:21.077+01:00</updated><title type='text'>The HTTP-API Family</title><content type='html'>fixme&lt;br/&gt;&lt;br/&gt;.. a classification of web apis to differentiate from rest and to make explicit their properties&lt;br/&gt;&lt;br/&gt;and what is saved by using them&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-788454429352835081?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/788454429352835081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/http-api-family.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/788454429352835081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/788454429352835081'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/http-api-family.html' title='The HTTP-API Family'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-7133201349422124073</id><published>2010-02-15T02:07:00.000+01:00</published><updated>2010-11-03T10:54:21.079+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Service Types'/><category scheme='http://www.blogger.com/atom/ns#' term='RESTifying Procurement'/><title type='text'>Service Types Revisited</title><content type='html'>Working on the RESTifying Procurement show case I realized that it looks as if I had to revisit my approach towards &lt;a href="http://www.nordsc.com/blog/?p=24"&gt;service types&lt;/a&gt;. I have argued that a service type is constituted by the set of hypermedia semantics it makes use of. This seemed reasonable since a client developer needs to know at least a minimal set of the possible hypermedia semantics to expect from a service in order to write a client for a service of that kind.&lt;br/&gt;&lt;br/&gt;Unfortunately this approach has some problems when services of different kinds use the same set of hypermedia semantics because the differentiating aspect is lost. I realized this because in the procurement example I am basically using a single &lt;a href="http://www.nordsc.com/blog/?p=293"&gt;media type&lt;/a&gt; but still have a &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html#PARTYROLES"&gt;range of services&lt;/a&gt;, for example supplier or carrier.&lt;br/&gt;&lt;br/&gt;A possible solution to this issue is to have the all-encompassing media type define the service types. Such types are still necessary to enable lookup based on type, for example in order to find the &lt;em&gt;carrier service&lt;/em&gt; of some external business partner. Looking for the &lt;em&gt;procurement service&lt;/em&gt; doesn't make that much sense.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-7133201349422124073?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/7133201349422124073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/service-types-revisited.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7133201349422124073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7133201349422124073'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/service-types-revisited.html' title='Service Types Revisited'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-3277444921202466571</id><published>2010-02-14T18:53:00.000+01:00</published><updated>2010-11-03T10:54:21.080+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST Design Mistakes'/><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Constraint'/><title type='text'>Markus Karg on the Hypermedia Constraint</title><content type='html'>As a &lt;a href="https://jersey.dev.java.net/servlets/ReadMsg?list=users&amp;msgNo=10027"&gt;reaction&lt;/a&gt; to the latest &lt;a href="http://weblogs.java.net/blog/spericas/archive/2010/02/09/exploring-hypermedia-support-jersey"&gt;experimental proposal&lt;/a&gt; for supporting hypermedia in Jersey, Markus chimed in, &lt;a href="http://weblogs.java.net/blog/mkarg/archive/2010/02/14/what-hateoas-actually-means"&gt;saying&lt;/a&gt;:&lt;br/&gt;&lt;blockquote&gt;If you want to gain all the benefits of REST, you need to apply all four constraints but not just three of them.&lt;/blockquote&gt;&lt;br/&gt;I whole-heartedly agree with that.&lt;br/&gt;&lt;br/&gt;However, I disagree with his analysis that only the response body (and not the headers) carries the hypermedia that represents the next application state. From a hypermedia constraint point of view it is irrelevant whether the hypermedia controls (that is links, link templates or forms) are placed inside the body or inside the HTTP headers.&lt;br/&gt;Placing the controls into the HTTP header can, for example, be a viable solution when you want to (or have to) use existing document formats for the body that do not provide the ability to place the controls in the body.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-3277444921202466571?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/3277444921202466571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/markus-karg-on-hypermedia-constraint_14.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3277444921202466571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3277444921202466571'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/markus-karg-on-hypermedia-constraint_14.html' title='Markus Karg on the Hypermedia Constraint'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-5944644786831040258</id><published>2010-02-14T18:45:00.000+01:00</published><updated>2010-11-03T10:54:21.081+01:00</updated><title type='text'>Markus Karg on the Hypermedia Constraint</title><content type='html'>As a &lt;a href="https://jersey.dev.java.net/servlets/ReadMsg?list=users&amp;msgNo=10027"&gt;reaction&lt;/a&gt; to the latest &lt;a href="http://weblogs.java.net/blog/spericas/archive/2010/02/09/exploring-hypermedia-support-jersey"&gt;experimental proposal&lt;/a&gt; for supporting hypermedia in Jersey, Markus chimed, in &lt;a href="http://weblogs.java.net/blog/mkarg/archive/2010/02/14/what-hateoas-actually-means"&gt;saying&lt;/a&gt;:&lt;br/&gt;&lt;blockquote&gt;If you want to gain all the benefits of REST, you need to apply all four constraints but not just three of them.&lt;/blockquote&gt;&lt;br/&gt;I whole-heartedly agree with that. In fact, I think that the application of REST in contexts outside the Web is in a rather vulnerable state because of the increasingly advertised misconceptions about REST.&lt;br/&gt;&lt;br/&gt;Applying REST to a problem space leads to significantly higher start-up efforts than solving the same problem for the given moment in time with any RPC technology. The reason to apply REST is to leverage the long term benefits induced by REST's architectural constraints and these benefits can only be leveraged if you apply all four of the constraints and not if you drop the hypermedia constraint. To quote Roy:&lt;br/&gt;&lt;blockquote&gt;Umm, no, it is essential to eliminate the coupling between client and server. If the application doesn't follow the workflow defined by the representations that are received, then the application isn't using the REST style. Not even a little bit. It is using RPC plus streaming, with a rather inefficient syntax, and the client will break each time the server's application evolves because the client must be anticipating the server's state based on its own assumptions. In other words, the two are coupled by their original design.&lt;/blockquote&gt;&lt;br/&gt;&lt;br/&gt;(From &lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/8380"&gt;rest-discuss #8380&lt;/a&gt;)&lt;br/&gt;&lt;br/&gt;Applying the hypermedia constraint has the implication that the client really must prepare for any kind of response by the server instead of relying on some undocumented out-of-band agreement between client and server. Maybe this implication seems so radical that&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-5944644786831040258?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/5944644786831040258/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/markus-karg-on-hypermedia-constraint.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5944644786831040258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5944644786831040258'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/markus-karg-on-hypermedia-constraint.html' title='Markus Karg on the Hypermedia Constraint'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-2475575763901766072</id><published>2010-02-13T12:48:00.000+01:00</published><updated>2010-11-03T10:54:21.082+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Brainstorm'/><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><category scheme='http://www.blogger.com/atom/ns#' term='Steady-States'/><title type='text'>Three Aspects of Steady-States</title><content type='html'>The #rest IRC channel (transcripts &lt;a href="http://rest.hackyhack.net/"&gt;here&lt;/a&gt; and &lt;a href="http://nordsc.com/transcripts/rest/"&gt;here&lt;/a&gt;) has recently become for me a valuable source for thought stimulation (come and visit). Yesterday we had a &lt;a href="http://rest.hackyhack.net/12Feb2010.html"&gt;discussion&lt;/a&gt; regarding &lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_3_3"&gt;steady-states&lt;/a&gt; and the following observation has been made:&lt;br/&gt;&lt;br/&gt;URIs refer to a certain application state; at least in the sense that one can use a URI to go back to a certain application state or that one can pass a URI to another party to bring this party into that application state.&lt;br/&gt;&lt;br/&gt;However, 'that application state' (despite the notion that I can use the URI to get back to it) is not stable over time. The semantics of the mapping are, but the transitions available form that state can change. So, what is the significance of 'that application state'?&lt;br/&gt;&lt;br/&gt;I have not figured that out yet, but here is a thought I had this morning as a reaction to the discussion:&lt;br/&gt;&lt;br/&gt;A Web application comprises a state machine that can change over time. Each state (aka &lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_3_3"&gt;steady-state&lt;/a&gt;)  of that state machine has three aspects:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;&lt;li&gt;Its semantics (what the state means)&lt;/li&gt;&lt;br/&gt;&lt;li&gt;The serialized state of the associated domain concept (e.g. order 10029)&lt;/li&gt;&lt;br/&gt;&lt;li&gt;The outgoing transitions to other states&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;&lt;br/&gt;The first of the three is constrained to remain stable over time the other two vary depending on the state of the associated domain concept and the actual state machine the server intends to provide to (that particular) client.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: It has come up in a number of places a notion of t&lt;a href="http://rest.hackyhack.net/2010-02-12.html#254/h254"&gt;ransient states&lt;/a&gt; or &lt;a href="http://iansrobinson.com/2010/02/12/london-geek-night/"&gt;ephemeral URI&lt;/a&gt;s. As far as I understand the issue circles around the idea of giving distinct URIs to different states of application states. With this approach, an order in some 'review-pending' state would be represented by a different resource (and hence different URI) than the same order in the state 'shipment-initiated'. Please correct me, if I miss the point here.&lt;br/&gt;&lt;br/&gt;My response to that can be found in this &lt;a href="http://iansrobinson.com/2010/02/12/london-geek-night/#comment-196"&gt;comment&lt;/a&gt; on &lt;a href="http://iansrobinson.com"&gt;Ian's blog&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;I'd highly apprechiate if someone could shed more light on this issue. I think it is a deep one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-2475575763901766072?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/2475575763901766072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/three-aspects-of-steady-states.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2475575763901766072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2475575763901766072'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/three-aspects-of-steady-states.html' title='Three Aspects of Steady-States'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-696376472579277620</id><published>2010-02-12T12:23:00.000+01:00</published><updated>2010-11-03T10:54:21.084+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UBL'/><category scheme='http://www.blogger.com/atom/ns#' term='RESTifying Procurement'/><title type='text'>RESTifying Procurement - Service Running</title><content type='html'>Though not much yet, I have put the procurement service online. At the moment, the service for the &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html#PARTYROLES"&gt;supplier party&lt;/a&gt; of the UBL business process is provided by the implementation. It can be accessed at http://labs.nordsc.com:8080/rp/supplier/service.&lt;br/&gt;&lt;br/&gt;&lt;pre lang="bash"&gt;&lt;br/&gt;$ curl http://labs.nordsc.com:8080/rp/supplier/service | tidy -xml -i -q&lt;br/&gt;&lt;br/&gt;&lt;service xmlns="http://www.w3.org/2007/app"&lt;br/&gt;xmlns:atom="http://www.w3.org/2005/Atom"&gt;&lt;br/&gt;  &lt;workspace&gt;&lt;br/&gt;    &lt;atom:title type="text"&gt;This service implements the UBL&lt;br/&gt;    supplier role.&lt;/atom:title&gt;&lt;br/&gt;    &lt;atom:link rel="common-catalogue"&lt;br/&gt;    href="http://labs.nordsc.com:8080/rp/supplier/provider/common-catalogue"&lt;br/&gt;    type="application/procurement+xml;type=catalogue"&lt;br/&gt;    title="The public catalogue"&gt;&lt;/atom:link&gt;&lt;br/&gt;  &lt;/workspace&gt;&lt;br/&gt;&lt;/service&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;The service document provides a link to the common catalogue provided by the provider role (here played by the supplier party). I explain the special use I make of AtomPub service documents in this &lt;a href="http://www.nordsc.com/blog/?p=80"&gt;post&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;A client that understands the 'common-catalogue' link relation and intends to look at the common catalogue can now do this:&lt;br/&gt;&lt;pre lang="bash"&gt;&lt;br/&gt;$ curl http://labs.nordsc.com:8080/rp/supplier/provider/common-catalogue | tidy -xml -i -q&lt;br/&gt;&lt;br/&gt;&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;br/&gt;&lt;?xml-stylesheet href='http://labs.nordsc.com:8080/rp/css/catalogue.css' type='text/css'?&gt;&lt;br/&gt;&lt;Catalog xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"&lt;br/&gt;xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"&lt;br/&gt;xmlns="urn:oasis:names:specification:ubl:schema:xsd:Catalogue-2"&gt;&lt;br/&gt;  &lt;cbc:ID&gt;public-001&lt;/cbc:ID&gt;&lt;br/&gt;  &lt;cbc:IssueDate&gt;2012-02-02&lt;/cbc:IssueDate&gt;&lt;br/&gt;  &lt;cac:CatalogueLine&gt;&lt;br/&gt;    &lt;cbc:ID&gt;1&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;      &lt;cac:Price&gt;&lt;br/&gt;        &lt;cbc:PriceAmount currencyID="EUR"&gt;16.90&lt;/cbc:PriceAmount&gt;&lt;br/&gt;      &lt;/cac:Price&gt;&lt;br/&gt;    &lt;/cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;    &lt;cac:Item&gt;&lt;br/&gt;      &lt;cbc:Name&gt;Valve 1-54&lt;/cbc:Name&gt;&lt;br/&gt;      &lt;cbc:Description&gt;This valve helps with a lot of&lt;br/&gt;      things&lt;/cbc:Description&gt;&lt;br/&gt;      &lt;cac:SellersItemIdentification&gt;&lt;br/&gt;        &lt;cbc:ID schemeURI="http://labs.nordsc.com/schemes/items/"&lt;br/&gt;        schemeDataURI="http://labs.nordsc.com:8080/rp//provider/items/"&gt;&lt;br/&gt;        PARTS-7615221&lt;/cbc:ID&gt;&lt;br/&gt;      &lt;/cac:SellersItemIdentification&gt;&lt;br/&gt;    &lt;/cac:Item&gt;&lt;br/&gt;  &lt;/cac:CatalogueLine&gt;&lt;br/&gt;&lt;cac:CatalogueLine&gt;&lt;br/&gt;    &lt;cbc:ID&gt;2&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;      &lt;cac:Price&gt;&lt;br/&gt;        &lt;cbc:PriceAmount currencyID="EUR"&gt;26.90&lt;/cbc:PriceAmount&gt;&lt;br/&gt;      &lt;/cac:Price&gt;&lt;br/&gt;    &lt;/cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;    &lt;cac:Item&gt;&lt;br/&gt;      &lt;cbc:Name&gt;Valve 2-54&lt;/cbc:Name&gt;&lt;br/&gt;      &lt;cbc:Description&gt;This valve helps with a lot of&lt;br/&gt;      things&lt;/cbc:Description&gt;&lt;br/&gt;      &lt;cac:SellersItemIdentification&gt;&lt;br/&gt;        &lt;cbc:ID schemeURI="http://labs.nordsc.com/schemes/items/"&lt;br/&gt;        schemeDataURI="http://labs.nordsc.com:8080/rp//provider/items/"&gt;&lt;br/&gt;        PARTS-7625222&lt;/cbc:ID&gt;&lt;br/&gt;      &lt;/cac:SellersItemIdentification&gt;&lt;br/&gt;    &lt;/cac:Item&gt;&lt;br/&gt;  &lt;/cac:CatalogueLine&gt;&lt;br/&gt;  &lt;cac:CatalogueLine&gt;&lt;br/&gt;    &lt;cbc:ID&gt;3&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;      &lt;cac:Price&gt;&lt;br/&gt;        &lt;cbc:PriceAmount currencyID="EUR"&gt;36.90&lt;/cbc:PriceAmount&gt;&lt;br/&gt;      &lt;/cac:Price&gt;&lt;br/&gt;    &lt;/cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;    &lt;cac:Item&gt;&lt;br/&gt;      &lt;cbc:Name&gt;Valve 3-54&lt;/cbc:Name&gt;&lt;br/&gt;      &lt;cbc:Description&gt;This valve helps with a lot of&lt;br/&gt;      things&lt;/cbc:Description&gt;&lt;br/&gt;      &lt;cac:SellersItemIdentification&gt;&lt;br/&gt;        &lt;cbc:ID schemeURI="http://labs.nordsc.com/schemes/items/"&lt;br/&gt;        schemeDataURI="http://labs.nordsc.com:8080/rp//provider/items/"&gt;&lt;br/&gt;        PARTS-7635223&lt;/cbc:ID&gt;&lt;br/&gt;      &lt;/cac:SellersItemIdentification&gt;&lt;br/&gt;    &lt;/cac:Item&gt;&lt;br/&gt;  &lt;/cac:CatalogueLine&gt;&lt;br/&gt;&lt;/Catalog&gt;&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;According to the to-be-written processing intent of application/procurement+xml a client could now select items from the catalogue and create an order from them. How that order looks and - more interesting - where to send that order will be the subject of one of the next posts.&lt;br/&gt;&lt;br/&gt;The implementation will serve the examples as application/xml to browsers thanks to Jersey's conneg support so you won't get an annoying download. There is also &lt;a href="http://labs.nordsc.com:8080/rp/css/catalogue.css"&gt;CSS styling&lt;/a&gt; of the XML so you can actually see something.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-696376472579277620?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/696376472579277620/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-service-running.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/696376472579277620'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/696376472579277620'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-service-running.html' title='RESTifying Procurement - Service Running'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-3955107519409922410</id><published>2010-02-12T02:44:00.000+01:00</published><updated>2010-11-03T10:54:21.086+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><category scheme='http://www.blogger.com/atom/ns#' term='UBL'/><category scheme='http://www.blogger.com/atom/ns#' term='RESTifying Procurement'/><title type='text'>RESTifying Procurement - The Media Type</title><content type='html'>In the examples throughout this series I am using (among others) the hypothetical media type application/procurement+xml. In this post I will start fleshing out its specification.&lt;br/&gt;&lt;br/&gt;A central aspect of the RESTifying Procurement project is the use of the UBL document family. UBL actually encourages adopters to customize the documents to suit the needs of the interacting parties which usually means specializing upon the very flexible UBL documents types. There are also guidelines for evolving the document types to forward incompatible new types but I'll rather stick with standard UBL.&lt;br/&gt;&lt;br/&gt;UBL has not been build with hypermedia in mind and does not provide explicit linking facilities. In order to address that limitation I'll define a special processing intent for &amp;lt;cbc:ID&amp;gt; elements, make use of HTTP Link headers and, where appropriate, use hypertext enabled media types such as application/atom+xml.&lt;br/&gt;&lt;br/&gt;The hypothetical media type application/procurement+xml encompasses specialized versions of several UBL document types and associates with them a processing model as far as that is necessary to enable the associated business processes to be carried out by software components communicating via HTTP.&lt;br/&gt;&lt;br/&gt;The current list of document types (which I will update when new types are added) is shown below. For every document type a value for a type parameter for the media type is provided to enable content negotiation based on the individual document types.&lt;br/&gt;&lt;br/&gt;&lt;style type="text/css"&gt;&lt;br/&gt;table.data { border-style: solid; border-width: 1px; border-spacing: 0px; padding: 0px; }&lt;br/&gt;table.data tr { padding: 0px; }&lt;br/&gt;table.data td { border-style: solid; border-width: 1px; padding: 5px; }&lt;br/&gt;&lt;/style&gt;&lt;br/&gt;&lt;br/&gt;&lt;table class="data"&gt;&lt;br/&gt;&lt;tr&gt;&lt;td&gt;UBL Document&lt;/td&gt;&lt;td&gt;type parameter value&lt;/td&gt;&lt;td&gt;RelaxNG Schema&lt;/td&gt;&lt;td&gt;Example&lt;/td&gt;&lt;tr&gt;&lt;br/&gt;&lt;tr&gt;&lt;td&gt;&lt;a name="catalogue"&gt;&lt;/a&gt;&lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/uml/UBL-2.0-CatalogueDocumentAssembly.html"&gt;Catalogue&lt;/a&gt;&lt;/td&gt;&lt;td&gt;catalogue&lt;/td&gt;&lt;td&gt;&lt;a target="_blank" href="http://labs.nordsc.com:8080/rp/rnc/Catalogue.rnc"/&gt;Catalogue.rnc&lt;/td&gt;&lt;td&gt;(&lt;a href="http://labs.nordsc.com:8080/rp/supplier/provider/common-catalogue"&gt;xml&lt;/a&gt;)&lt;/td&gt;&lt;tr&gt;&lt;br/&gt;&lt;tr&gt;&lt;td&gt;&lt;a name="order"&gt;&lt;/a&gt;&lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/uml/UBL-2.0-OrderDocumentAssembly.html"&gt;Order&lt;/a&gt;&lt;/td&gt;&lt;td&gt;order&lt;/td&gt;&lt;td&gt;&lt;a target="_blank" href="http://labs.nordsc.com:8080/rp/rnc/Order.rnc"/&gt;Order.rnc &lt;/td&gt;&lt;td&gt;(&lt;a href="http://labs.nordsc.com:8080/rp/supplier/seller/customers/8872/orders/188.2221.8"&gt;xml&lt;/a&gt;)&lt;/td&gt;&lt;tr&gt;&lt;br/&gt;&lt;/table&gt;&lt;br/&gt;&lt;br/&gt;&lt;a name="cbcID-tweak"&gt;&lt;/a&gt;&lt;br/&gt;&lt;strong&gt;Additional Processing Rules for the &amp;lt;cbc:ID&amp;gt; Element&lt;/strong&gt;&lt;br/&gt;The &amp;lt;cbc:ID&amp;gt; element is used throughout the UBL for identification. Various attributes can be used to identify the schema to which the identifier itself belongs. A common use of the element would be&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;br/&gt;&lt;cbc:ID schemeURI="http://labs.nordsc.com/schemes/products"&gt;&lt;br/&gt;  PARTS-7635223&lt;/cbc:ID&gt;&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Which means that the thing being identified has the identifier &lt;em&gt;PARTS-7635223&lt;/em&gt; and that this identifier is taken from the scheme (namespace) identified by &lt;em&gt;http://labs.nordsc.com/schemes/products&lt;/em&gt;. This is similar to &lt;a href="http://tools.ietf.org/html/rfc4287#section-4.2.2"&gt;Atom's &amp;lt;category&amp;gt; element&lt;/a&gt; that combines a scheme and a term attribute for the same purpose.&lt;br/&gt;&lt;br/&gt; Unfortunately, the element does not directly provide for the use of URIs for identification, meaning that one &lt;strong&gt;cannot&lt;/strong&gt; do something like this:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;br/&gt;&lt;cbc:ID href="http://labs.nordsc.com/repository/items/1234"&gt;&lt;br/&gt;  1234&lt;/cbc:ID&gt;&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;That is a strange situation (at least in Web context): UBL provides an element for identification but does not support the use of URIs as identifiers. To solve this, I decided to cheat a little and turn the &amp;lt;cbc:ID&amp;gt; element into a hyperlink.&lt;br/&gt;&lt;br/&gt;The &amp;lt;cbc:ID&amp;gt; element provides an attribute named schemeDataURI that enables authors to reference a resource where the scheme data is available (the list of all identifiers and their description). &lt;br/&gt;&lt;br/&gt;What if I defined the processing intention of application/procurement+xml to understand the concatenation of the schemeDataURI and the actual identifier to be a URI identifier for the thing identified by the given &amp;lt;cbc:ID&amp;gt; element? Yes, that would enable &amp;lt;cbc:ID&amp;gt; to turn into a hyperlink.&lt;br/&gt;&lt;br/&gt;An element such as&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;br/&gt;&lt;cbc:ID schemeURI="http://labs.nordsc.com/schemes/items/"&lt;br/&gt;  schemeDataURI="http://labs.nordsc.com/service/items/"&gt;&lt;br/&gt;  PARTS-7635223&lt;/cbc:ID&gt;&lt;br/&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;can then be interpreted as a link referencing &lt;em&gt;http://labs.nordsc.com/service/items/PARTS-7635223&lt;/em&gt;.&lt;br/&gt;&lt;br/&gt;For now the specification of application/procurement+xml consists of the specialized Catalogue document type and the special processing rule for &amp;lt;cbc:ID&amp;gt; element.&lt;br/&gt;&lt;br/&gt;I will update this posting as the media type grows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-3955107519409922410?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/3955107519409922410/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-media-type.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3955107519409922410'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3955107519409922410'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-media-type.html' title='RESTifying Procurement - The Media Type'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-7054396539854384946</id><published>2010-02-10T13:22:00.000+01:00</published><updated>2010-11-03T10:54:21.088+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST Design Mistakes'/><category scheme='http://www.blogger.com/atom/ns#' term='REST Frameworks'/><title type='text'>More Comments on Jersey</title><content type='html'>This &lt;a href="https://jersey.dev.java.net/servlets/ReadMsg?list=users&amp;msgNo=9921"&gt;posting&lt;/a&gt; to the Jersey user's list provides more detailed comments, explaining my concerns.&lt;br/&gt;&lt;br/&gt;UPDATE: The thread started by the reference above turned out to be rather interesting. It's worth a look.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-7054396539854384946?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/7054396539854384946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/more-comments-on-jersey.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7054396539854384946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7054396539854384946'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/more-comments-on-jersey.html' title='More Comments on Jersey'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-4477312878304727726</id><published>2010-02-09T22:49:00.000+01:00</published><updated>2010-11-03T10:54:21.090+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST Frameworks'/><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>Jersey Going Astray?</title><content type='html'>Santiago Pericas-Geertsen today &lt;a href="http://weblogs.java.net/blog/spericas/archive/2010/02/09/exploring-hypermedia-support-jersey"&gt;wrote&lt;/a&gt; about the approach currently taken by Jersey towards providing active server-side support for the hypermedia constraint.&lt;br/&gt;&lt;br/&gt;Given the exposure of Jersey I am worried to say the least.&lt;br/&gt;&lt;br/&gt;Santiago writes:&lt;br/&gt;&lt;blockquote&gt;It has been identified by other authors that there are actions that cannot be easily mapped to read or write operations on resources.&lt;/blockquote&gt;&lt;br/&gt;This quote creates the impression as if there was a problem that needed to be solved and that Jersey will help developers to solve it. This scares me!&lt;br/&gt;&lt;br/&gt;It scares me because it looks as if one of the most exposed RESTful HTTP frameworks is about to evolve not on the basis of how to enforce RESTful systems but based on a likely misconception of REST. What we need is to help architects and developers to design RESTful REST systems and not support REST misconceptions by hard coding them into a framework. Apologies if this sounds insulting, I don't mean to be. I am just worried.&lt;br/&gt;&lt;br/&gt;Here is the misconception: with REST, we do not map actions to read or write operations on resources but we achieve coordination between processes by transferring representations. Representations sent from server to client advance the client's application state and representations that are sent from client to server change resource state. The notions of 'action' and 'read or write' resources simply do not exist in REST and just because some authors have identified a problem related to these notions should not drive the evolution of JSR311.&lt;br/&gt;&lt;br/&gt;In REST a coordination goal is achieved by changing the state of a resource that has the proper semantics. All that is needed is the specification of media types that provide the necessary hypermedia semantics for the client to find such proper resources. RESTful frameworks should encourage the design of proper media types and ideally enforce correct client side behavior instead of introducing a concept of 'action resources' that just does not exist in REST.&lt;br/&gt;&lt;br/&gt;The primary design artifact for RESTful services is media types, link relations, etc. (there just is nothing else to design) and behind those is very serious and time consuming design work. Pretending that a framework (let alone 'action resources') could make this any simpler is misleading.&lt;br/&gt;&lt;br/&gt;I guess I have now put myself in a position of having to provide more constructive feedback :-) I'll give that a try tomorrow.&lt;br/&gt;&lt;br/&gt;And apologies again to those people whose work I am criticizing.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;: &lt;a href="http://www.headcrashing.eu/"&gt;Markus Karg&lt;/a&gt; &lt;a href="https://jersey.dev.java.net/servlets/ReadMsg?list=users&amp;msgNo=10027"&gt;chimes in&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-4477312878304727726?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/4477312878304727726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/jersey-going-astray.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4477312878304727726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4477312878304727726'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/jersey-going-astray.html' title='Jersey Going Astray?'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6997936188662337431</id><published>2010-02-09T12:29:00.000+01:00</published><updated>2010-11-03T10:54:21.092+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><category scheme='http://www.blogger.com/atom/ns#' term='UBL'/><category scheme='http://www.blogger.com/atom/ns#' term='RESTifying Procurement'/><title type='text'>RESTifying Procurement – Sourcing Part 2</title><content type='html'>In this part of the procurement series I describe the minimal UBL Catalogue document subset used for RESTful sourcing. In the &lt;a href="http://www.nordsc.com/blog/?p=217"&gt;previous part&lt;/a&gt; I have already presented the minimal HTTP interaction to send a public catalogue to a client and in this posting I'll show what information the catalogue needs to contain to enable the client to perform the next procurement step: &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html#d0e1629"&gt;ordering&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;The intention of a catalogue is to inform the receiver what items are available and to what prices and conditions. This information is then used by the receiver when constructing an order. One way to implement this pattern would be to make the catalogue a form, let the receiver select items within the form and finally let the receiver place an order by submitting the form. However, I'll have to take a different approach because on the one hand, there might be multiple catalogues involved in the 'shopping process' before the ordering and on the other hand, a forms based approach is not possible when using UBL documents because they do not provide forms.&lt;br/&gt;&lt;br/&gt;The UBL based solution is to list available items in the catalogue document and to provide SellersItemIdentification information for each item that the receiver can use to construct the order. This is essentially a client-side shopping cart pattern in which the client collects item identifiers and then submits the collected set as an order.&lt;br/&gt;&lt;br/&gt;Here is the UBL catalogue (I did not define a schema, the intention is that the example document shows the possible elements):&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;GET /provider/common-catalogue&lt;br/&gt;Accept: application/procurement+xml&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Content-Type: application/procurement+xml&lt;br/&gt;ETag: public-001&lt;br/&gt;Cache-Control: public,must-revalidate&lt;br/&gt;&lt;br/&gt;&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;br/&gt;&lt;?xml-stylesheet href='/css/catalogue.css' type='text/css'?&gt;&lt;br/&gt;&lt;Catalog xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"&lt;br/&gt;xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"&lt;br/&gt;xmlns="urn:oasis:names:specification:ubl:schema:xsd:Catalogue-2"&gt;&lt;br/&gt;  &lt;cbc:ID&gt;public-001&lt;/cbc:ID&gt;&lt;br/&gt;  &lt;cbc:IssueDate&gt;2012-02-02&lt;/cbc:IssueDate&gt;&lt;br/&gt;  &lt;cac:CatalogueLine&gt;&lt;br/&gt;    &lt;cbc:ID&gt;1&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;      &lt;cac:Price&gt;&lt;br/&gt;        &lt;cbc:PriceAmount currencyID="EUR"&gt;16.90&lt;/cbc:PriceAmount&gt;&lt;br/&gt;      &lt;/cac:Price&gt;&lt;br/&gt;    &lt;/cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;    &lt;cac:Item&gt;&lt;br/&gt;      &lt;cbc:Name&gt;Valve 1-54&lt;/cbc:Name&gt;&lt;br/&gt;      &lt;cbc:Description&gt;This valve helps with a lot of&lt;br/&gt;      things&lt;/cbc:Description&gt;&lt;br/&gt;      &lt;cac:SellersItemIdentification&gt;&lt;br/&gt;        &lt;cbc:ID&gt;PARTS-7615221&lt;/cbc:ID&gt;&lt;br/&gt;      &lt;/cac:SellersItemIdentification&gt;&lt;br/&gt;    &lt;/cac:Item&gt;&lt;br/&gt;  &lt;/cac:CatalogueLine&gt;&lt;br/&gt;  &lt;cac:CatalogueLine&gt;&lt;br/&gt;    &lt;cbc:ID&gt;2&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;      &lt;cac:Price&gt;&lt;br/&gt;        &lt;cbc:PriceAmount currencyID="EUR"&gt;26.90&lt;/cbc:PriceAmount&gt;&lt;br/&gt;      &lt;/cac:Price&gt;&lt;br/&gt;    &lt;/cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;    &lt;cac:Item&gt;&lt;br/&gt;      &lt;cbc:Name&gt;Valve 2-54&lt;/cbc:Name&gt;&lt;br/&gt;      &lt;cbc:Description&gt;This valve helps with a lot of&lt;br/&gt;      things&lt;/cbc:Description&gt;&lt;br/&gt;      &lt;cac:SellersItemIdentification&gt;&lt;br/&gt;        &lt;cbc:ID&gt;PARTS-7625222&lt;/cbc:ID&gt;&lt;br/&gt;      &lt;/cac:SellersItemIdentification&gt;&lt;br/&gt;    &lt;/cac:Item&gt;&lt;br/&gt;  &lt;/cac:CatalogueLine&gt;&lt;br/&gt;  &lt;cac:CatalogueLine&gt;&lt;br/&gt;    &lt;cbc:ID&gt;3&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;      &lt;cac:Price&gt;&lt;br/&gt;        &lt;cbc:PriceAmount currencyID="EUR"&gt;36.90&lt;/cbc:PriceAmount&gt;&lt;br/&gt;      &lt;/cac:Price&gt;&lt;br/&gt;    &lt;/cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;    &lt;cac:Item&gt;&lt;br/&gt;      &lt;cbc:Name&gt;Valve 3-54&lt;/cbc:Name&gt;&lt;br/&gt;      &lt;cbc:Description&gt;This valve helps with a lot of&lt;br/&gt;      things&lt;/cbc:Description&gt;&lt;br/&gt;      &lt;cac:SellersItemIdentification&gt;&lt;br/&gt;        &lt;cbc:ID&gt;PARTS-7635223&lt;/cbc:ID&gt;&lt;br/&gt;      &lt;/cac:SellersItemIdentification&gt;&lt;br/&gt;    &lt;/cac:Item&gt;&lt;br/&gt;  &lt;/cac:CatalogueLine&gt;&lt;br/&gt;&lt;/Catalog&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Let's analyze that in chunks. Here is the top:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;?xml version='1.0' encoding='utf-8'?&gt;&lt;br/&gt;&lt;?xml-stylesheet href='/css/catalogue.css' type='text/css'?&gt;&lt;br/&gt;&lt;Catalog xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"&lt;br/&gt;xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"&lt;br/&gt;xmlns="urn:oasis:names:specification:ubl:schema:xsd:Catalogue-2"&gt;&lt;br/&gt;  &lt;cbc:ID&gt;public-001&lt;/cbc:ID&gt;&lt;br/&gt;  &lt;cbc:IssueDate&gt;2012-02-02&lt;/cbc:IssueDate&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;The top of the document contains UBL-specific namespace declarations and a catalogue ID and issue date. For debugging purposes, it is useful to provide a style sheet for rendering the catalogue in a browser, so an xml-stylesheet PI is included also.&lt;br/&gt;&lt;br/&gt;The catalogue consists of catalog lines that each contain information of one offered item:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;cac:CatalogueLine&gt;&lt;br/&gt;    &lt;cbc:ID&gt;3&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;      &lt;cac:Price&gt;&lt;br/&gt;        &lt;cbc:PriceAmount currencyID="EUR"&gt;36.90&lt;/cbc:PriceAmount&gt;&lt;br/&gt;      &lt;/cac:Price&gt;&lt;br/&gt;    &lt;/cac:RequiredItemLocationQuantity&gt;&lt;br/&gt;    &lt;cac:Item&gt;&lt;br/&gt;      &lt;cbc:Name&gt;Valve 3-54&lt;/cbc:Name&gt;&lt;br/&gt;      &lt;cbc:Description&gt;This valve helps with a lot of&lt;br/&gt;      things&lt;/cbc:Description&gt;&lt;br/&gt;      &lt;cac:SellersItemIdentification&gt;&lt;br/&gt;        &lt;cbc:ID&gt;PARTS-7635223&lt;/cbc:ID&gt;&lt;br/&gt;      &lt;/cac:SellersItemIdentification&gt;&lt;br/&gt;    &lt;/cac:Item&gt;&lt;br/&gt;  &lt;/cac:CatalogueLine&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;This example catalogue line describes the item &lt;em&gt;Valve 3-54&lt;/em&gt; is available at a price of &lt;em&gt;EUR 36.90&lt;/em&gt; and that the item is identified in the seller's system by the ID &lt;em&gt;PARTS-7635223&lt;/em&gt;. This seller's item identification is what the buyer later on must use for constructing its order.&lt;br/&gt;&lt;br/&gt;How does the client know that? This is information that needs to be covered by the media type specification. Therefore, the specification of the hypothetical media type application/procurement+xml would need to specify that catalogue documents' catalogue lines contain seller system IDs and that these must be used in the corresponding fields of order documents.&lt;br/&gt;&lt;br/&gt;This highlights the distinction between document schema and intended processing and why it is not enough to send the catalogue as application/xml, for example. It is exactly the hypermedia model (e.g. "take the seller's item IDs and put them in your order later on") that is defined by the media type and cannot be defined by a schema.&lt;br/&gt;&lt;br/&gt;Why do I use a common media type for all UBL documents (application/procurement+xml) as opposed to one media type for each UBL document (e.g. application/ubl-catalogue+xml)?&lt;br/&gt;&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;A single generic media type prevents the creation of possibly many specific types; this in my experience simplifies development&lt;/li&gt;&lt;br/&gt;&lt;br/&gt;	&lt;li&gt;Media types commonly identify the application that should be used to process them, so it seems consistent to think of an application that handles procurement related documents and figures out internally which specific document it has been given.&lt;/li&gt;&lt;br/&gt;&lt;br/&gt;	&lt;li&gt;A type parameter can be used for content negotiation and related aspects such as declaring what format to send to certain resources. For example, in order to tell a client that an AtomPub collection accepts orders &amp;lt;accept&amp;gt;application/procurement+xml;type=Order&amp;lt;/accept&amp;gt; does the job.&lt;/li&gt;&lt;br/&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;br/&gt;There is another aspect of the media type design which I will cover in one of the next parts: The primary purpose of an HTTP response is not to transfer a serialized domain object (e.g. a catalogue) but to put the client in a certain application state. Therefore, media type design must be primarily concerned with the question of what the intended application state is. The decision to make use of UBL for the procurement example series limits the design space because I cannot simply add necessary control data and/or links to UBL.&lt;br/&gt;&lt;br/&gt;The way to solve this problem is to make use of HTTP Link headers to provide clients with information such as where to send an order once it is constructed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6997936188662337431?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6997936188662337431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-sourcing-part-2.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6997936188662337431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6997936188662337431'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-sourcing-part-2.html' title='RESTifying Procurement – Sourcing Part 2'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8595702015495161610</id><published>2010-02-08T11:58:00.000+01:00</published><updated>2010-11-03T10:54:21.095+01:00</updated><title type='text'>REST Web services with Yaws Yapps</title><content type='html'>INTRO&lt;br/&gt;&lt;br/&gt;First, you need to build and install yapps because it is not installed during the yaws standard build and install.&lt;br/&gt;&lt;br/&gt;&lt;pre lang="shell"&gt;&lt;br/&gt;$ cd yaws-1.87/applications/yapp&lt;br/&gt;$ make&lt;br/&gt;$ make install&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Then Yaws needs to be made aware of the yapp module. I followed the instructions in the &lt;a href="http://yaws.hyber.org/yapp_intro.yaws"&gt;yapps intro&lt;/a&gt;. This worked pretty much, but I had to look up the yapp's ebin directory from the yapp Makefile beause it was not below Yaws' root directory as the intro suggests.&lt;br/&gt;&lt;br/&gt;&lt;a href="http://yaws.hyber.org/yapp_intro.yaws"&gt;yapps introduction&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8595702015495161610?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8595702015495161610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/rest-web-services-with-yaws-yapps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8595702015495161610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8595702015495161610'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/rest-web-services-with-yaws-yapps.html' title='REST Web services with Yaws Yapps'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-860085489314806847</id><published>2010-02-07T22:00:00.000+01:00</published><updated>2010-11-03T10:54:21.096+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Yaws'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='CouchDB'/><title type='text'>Setting up Erlang, Yaws and CouchDB</title><content type='html'>First I thought I'd develop the practical examples for my RESTifying Procurement experiment on the basis of &lt;a href="https://jersey.dev.java.net/"&gt;Jersey&lt;/a&gt; but fortunately before I started I realized the obvious opportunity to dive into Erlang and CouchDB. Hence here we go.&lt;br/&gt;&lt;br/&gt;This is a very brief list of more or less painful steps I had to go through to set up a basic environment on the server hosted by my ISP:&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;Download latest Erlang sources from &lt;a href="http://www.erlang.org"&gt;erlang.org&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Run configure script...to find out that my ISP provides only a considered-broken gcc with its SuSE distro and updates&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Download newer, fixed gcc sources and compile fixed gcc with broken gcc&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Compile Erlang with fixed gcc (smooth compile and install now)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Download &lt;a href="http://yaws.hyber.org/"&gt;Yaws&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Compile, install, configure and start Yaws (super easy)&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;Download &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;Compile, install CouchDB&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;In between I had to add &lt;a href="http://packman.links2linux.org/"&gt;PackMan&lt;/a&gt;'s SuSE repository to yast to get hold of some packages that are apparently unknown to my ISP's SuSE repository and figuring this out was rather time consuming because I usually do not spend much time with SuSE administration issues these days.&lt;br/&gt;&lt;br/&gt;I had two Erlang books (&lt;a href="http://www.erlangprogramming.org/"&gt;Erlang Programming&lt;/a&gt; and &lt;a href="http://www.pragprog.com/titles/jaerlang/programming-erlang"&gt;Programming Erlang&lt;/a&gt;) waiting on my shelf for me and spent my (little) free time over the weekend to get my feet wet. So far, I am mostly fascinated because I have never done functional programming before.&lt;br/&gt;&lt;br/&gt;What I found kind of difficult was to find documentation and code snippets and decide about their quality and whether they reflect current practice. Here is the list of links I have dug up so far and consider prime content:&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://www.erlang.org"&gt;The Erlang Web site&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://yaws.hyper.org"&gt;The Yaws Web site&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://www.infoq.com/articles/vinoski-erlang-rest"&gt;RESTful Web services with Erlang and Yaws&lt;/a&gt; (Steve Vinoski)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://steve.vinoski.net/pdf/IC-Build_Your_Next_Web_Application_with_Erlang.pdf"&gt;Build you next Web application with Erlang&lt;/a&gt; (Dave Bryson, Steve Vinoski)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://blog.socklabs.com/2008/04/09/a_restful_web_service_demo_in.html"&gt;A RESTful we service demo in yaws&lt;/a&gt; (Nick Gerakines)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://steve.vinoski.net/blog/"&gt;Steve Vinsoki's blog&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://blog.socklabs.com/"&gt;Nick Gerakines' blog&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://www.infoq.com/presentations/erlang-software-for-a-concurrent-world"&gt;Erlang - software for a concurrent world&lt;/a&gt; (Presentation by Joe Armstrong)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;a href="http://www.infoq.com/presentations/Systems-that-Never-Stop-Joe-Armstrong"&gt;Systems that never stop (and Erlang)&lt;/a&gt; (Presentation by Joe Armstrong)&lt;/li&gt;&lt;br/&gt;        &lt;li&gt;(&lt;strong&gt;UPDATE&lt;/strong&gt;) &lt;a href="http://www.erlang.org/doc/design_principles/users_guide.html"&gt;OTP Design Principles User's Guide&lt;/a&gt;&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;That's it for now. When I dig up more articles I'll append them here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-860085489314806847?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/860085489314806847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/setting-up-erlang-yaws-and-couchdb.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/860085489314806847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/860085489314806847'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/setting-up-erlang-yaws-and-couchdb.html' title='Setting up Erlang, Yaws and CouchDB'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-4258054513484063357</id><published>2010-02-04T16:07:00.000+01:00</published><updated>2010-11-03T10:54:21.098+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Separation of Concerns'/><category scheme='http://www.blogger.com/atom/ns#' term='RESTifying Procurement'/><title type='text'>RESTifying Procurement - Sourcing Part 1</title><content type='html'>&lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html#d0e1458"&gt;Sourcing&lt;/a&gt; refers to the procurement process where one party role (the provider) provides another party role (the receiver) with a catalogue. A catalogue is a document that describes items and prices.&lt;br/&gt;&lt;br/&gt;The first thing to do is to differentiate server side role and client side role to achieve clean separation of concerns. A good hint for identifying the server side role is where the application data is located. In the case of sourcing, the party that plays the provider role owns the item data that is used to create the catalogues. Therefore it is straight-forward to implement the provider role as a service and make the receiver role a client.&lt;br/&gt;&lt;br/&gt;&lt;a href="http://www.nordsc.com/blog/wp-content/uploads/2010/02/Sourcing_1.jpg"&gt;&lt;img src="http://www.nordsc.com/blog/wp-content/uploads/2010/02/Sourcing_1-300x107.jpg" alt="" title="Sourcing_1" width="300" height="107" class="aligncenter size-medium wp-image-222" /&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;As I &lt;a href="http://lists.oasis-open.org/archives/ubl-dev/201002/msg00005.html"&gt;learned&lt;/a&gt; today, UBL does not specify the actual procurement processes but merely provides the set of business documents to choose from when designing your own processes. This is nice, because it mens that UBL can be suitably applied even in the context of this little experiment.&lt;br/&gt;&lt;br/&gt;As a first step, the provider role service will just provide a public catalogue, let's say at http://labs.nordsc.com/procurement/roles/provider/common-catalogue.&lt;br/&gt;&lt;br/&gt;Assuming the receiver role client discovered that URL from the service document describing the provider service the following HTTP interaction could take place for catalogue provisioning:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;GET /procurement/roles/provider/common-catalogue&lt;br/&gt;Host: labs.nordsc.com&lt;br/&gt;Accept: application/vnd.nordsc.procurement+xml&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Content-Type: application/vnd.nordsc.procurement+xml&lt;br/&gt;Cache-Control: public,must-revalidate&lt;br/&gt;ETag: 1&lt;br/&gt;&lt;br/&gt;&lt;?xml version="1.0"?&gt;&lt;br/&gt;&lt;Catalogue xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"&lt;br/&gt;    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"&lt;br/&gt;    xmlns="urn:oasis:names:specification:ubl:schema:xsd:Catalogue-2"&lt;br/&gt; "&gt;&lt;br/&gt;    &lt;cbc:ID&gt;public-001&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cbc:IssueDate&gt;2010-02-02&lt;/cbc:IssueDate&gt;&lt;br/&gt;    &lt;cac:CatalogueLine&gt;&lt;br/&gt;        &lt;cbc:ID&gt;ID0&lt;/cbc:ID&gt;&lt;br/&gt;        &lt;cac:Item/&gt;&lt;br/&gt;    &lt;/cac:CatalogueLine&gt;&lt;br/&gt;&lt;/Catalogue&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;The catalogue representation is only a stub at the moment, we'll get to the media type issues later. Of particular interest is the caching policy for catalogues because the intention is for clients to use the latest catalogue data when placing an order. Catalogues can be potentially very large and we want them to be cached by public and private caches (Cache-Control: public) . However, since the freshness of the catalogue is very important, caches are instructed to never return a cached copy without prior revalidation (Cache-Control: must-revalidate).&lt;br/&gt;&lt;br/&gt;Apart from the issue of the media type for the catalogue, we have now designed the most simple version of &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html#d0e1477"&gt;catalogue provisioning&lt;/a&gt;. It will be interesting to explore how other sourcing interactions (for example &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html#d0e1597"&gt;customer initiated sourcing&lt;/a&gt;) can later on be added.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-4258054513484063357?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/4258054513484063357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-sourcing-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4258054513484063357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4258054513484063357'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-sourcing-part-1.html' title='RESTifying Procurement - Sourcing Part 1'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-2452181065081588755</id><published>2010-02-04T09:35:00.000+01:00</published><updated>2010-11-03T10:54:21.100+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Service Types'/><title type='text'>Service Type == Set of Possible Application States</title><content type='html'>As I have said earlier, in my opinion &lt;a href="http://"&gt;service types&lt;/a&gt; are defined by the set of hypermedia semantics (media types, link relations, ..) they use. Because representations sent by services of a given type are composed of hypermedia semantics from the service type's set it can be said that the service type defines the set of possible representations.&lt;br/&gt;&lt;br/&gt;Given that a representation returned by a server corresponds to an application state it follows that a service type defines the set of possible application states.&lt;br/&gt;&lt;br/&gt;I like that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-2452181065081588755?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/2452181065081588755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/service-type-set-of-possible.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2452181065081588755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/2452181065081588755'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/service-type-set-of-possible.html' title='Service Type == Set of Possible Application States'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-4901590545065853296</id><published>2010-02-03T17:53:00.000+01:00</published><updated>2010-11-03T10:54:21.102+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RESTifying Procurement'/><title type='text'>RESTifying Procurement - Introduction</title><content type='html'>For the purpose of this series of postings I view Procurement as a collection of business processes (e.g. &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html#d0e1458"&gt;sourcing&lt;/a&gt;, &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html#d0e1629"&gt;ordering&lt;/a&gt;) and associated business documents (e.g. catalogue, &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/xml/UBL-Order-2.0-Example.xml"&gt;order&lt;/a&gt;). The goal is to design the necessary kinds of services and media types to enable the procurement processes to be executed between software components using HTTP.&lt;br/&gt;&lt;br/&gt;A practical way to start looking for necessary services is to think about the roles played by the parties participating in the processes (in a real scenario though, legacy systems are likely to influence the actual design).&lt;br/&gt;&lt;br/&gt;REST is a client-server architectural style, employing the principle of separation of concerns and therefore we need to differentiate between client roles and server roles. If client and server roles are not separated correctly the application state that pertains to a given collaboration might in part be located on the client which would result in unnecessary complexity. (This issue should be addressed by a separate posting but I have written up some &lt;a href="http://www.nordsc.com/blog/?p=18"&gt;thoughts&lt;/a&gt; about it earlier).&lt;br/&gt;&lt;br/&gt;Once the kinds of services are becoming clear the media types need to be designed. On the one hand these media types must be capable of expressing the domain information expressed by the various UBL documents, on the other hand, they must provide the proper linking semantics for the business process to advance. It is important to keep in mind that resource representations primarily transfer application state and not serialized domain objects.&lt;br/&gt;&lt;br/&gt;Once the kinds of services and the media types are designed, I'll take a look at the client programming model because one of the primary objectives of this exercise is to discuss how clients can cope with the evolvability granted to the server side by REST.&lt;br/&gt;&lt;br/&gt;At the moment I really plan to provide an example implementation of the services to address associated development issues and make the whole example more practical. Let's see how that works out though.&lt;br/&gt;&lt;br/&gt;This morning I have already worked on defining a manageable subset of UBL catalogue documents to support the sourcing process. Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-4901590545065853296?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/4901590545065853296/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-introduction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4901590545065853296'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4901590545065853296'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement-introduction.html' title='RESTifying Procurement - Introduction'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1532684522981483199</id><published>2010-02-03T14:41:00.000+01:00</published><updated>2010-11-03T10:54:21.105+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RESTifying Procurement'/><title type='text'>RESTifying Procurement</title><content type='html'>As more and more people are being attracted to applying REST in an enterprise IT context the lack of a non-trival practical example becomes increasingly apparent . Such an example would ideally cover all the aspects of RESTful integration and make visible the principles that can be applied during the individual design steps.&lt;br/&gt;&lt;br/&gt;Ideally, the example would also help people avoid the &lt;a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven"&gt;pitfalls of unRESTful REST&lt;/a&gt; by discussing related REST anti patterns.&lt;br/&gt;&lt;br/&gt;With this entry I'll start the journey to fill the void and develop an extended, practical example by RESTifying procurement.&lt;br/&gt;&lt;br/&gt;The conceptual basis will be the &lt;a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ubl"&gt;Universal Business Language&lt;/a&gt; because it provides a customizable set of the necessary business level documents and a rather clear description of the &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/UBL-2.0.html"&gt;business processes&lt;/a&gt; involved.&lt;br/&gt;&lt;br/&gt;Wish me luck.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1532684522981483199?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1532684522981483199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1532684522981483199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1532684522981483199'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/restifying-procurement.html' title='RESTifying Procurement'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-7953562172783715652</id><published>2010-02-03T13:07:00.000+01:00</published><updated>2010-11-03T10:54:21.106+01:00</updated><title type='text'></title><content type='html'>&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;br/&gt;GET /catalogues/public/1&lt;br/&gt;Accept: application/procurement+xml&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Content-Type: application/procurement+xml&lt;br/&gt;Cache-Control: public,must-revalidate&lt;br/&gt;ETag: 1234&lt;br/&gt;&lt;br/&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;br/&gt;&lt;Catalogue xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"&lt;br/&gt; xmlns:ns2="urn:un:unece:uncefact:codelist:specification:IANAMIMEMediaType:2003"&lt;br/&gt; xmlns:ns3="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"&lt;br/&gt; xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"&lt;br/&gt; xmlns:ns5="urn:un:unece:uncefact:codelist:specification:5639:1988"&lt;br/&gt; xmlns:ns6="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"&lt;br/&gt; xmlns:ns7="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"&lt;br/&gt; xmlns="urn:oasis:names:specification:ubl:schema:xsd:Catalogue-2"&lt;br/&gt; xmlns:ns9="urn:un:unece:uncefact:codelist:specification:54217:2001"&lt;br/&gt; xmlns:ns10="urn:un:unece:uncefact:codelist:specification:66411:2001"&lt;br/&gt; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&lt;br/&gt; xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Catalogue-2 file:/Users/algermissen1971/Resources/UBL/os-UBL-2.0/xsd/maindoc/UBL-Catalogue-2.0.xsd"&gt;&lt;br/&gt;    &lt;cbc:ID&gt;public-001&lt;/cbc:ID&gt;&lt;br/&gt;    &lt;cbc:IssueDate&gt;2010-02-02&lt;/cbc:IssueDate&gt;&lt;br/&gt;    &lt;cac:ProviderParty&gt;&lt;br/&gt;    &lt;/cac:ProviderParty&gt;&lt;br/&gt;    &lt;cac:ReceiverParty&gt;&lt;br/&gt;    &lt;/cac:ReceiverParty&gt;&lt;br/&gt;    &lt;cac:CatalogueLine&gt;&lt;br/&gt;        &lt;cbc:ID&gt;ID0&lt;/cbc:ID&gt;&lt;br/&gt;        &lt;cac:Item&gt;&lt;br/&gt;        &lt;/cac:Item&gt;&lt;br/&gt;    &lt;/cac:CatalogueLine&gt;&lt;br/&gt;&lt;/Catalogue&gt;&lt;br/&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-7953562172783715652?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/7953562172783715652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/get-cataloguespublic1-accept.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7953562172783715652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7953562172783715652'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/get-cataloguespublic1-accept.html' title=''/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-178670280565108736</id><published>2010-02-03T13:01:00.000+01:00</published><updated>2010-11-03T10:54:21.108+01:00</updated><title type='text'></title><content type='html'>In this entry ...&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;(10:00 AM)&lt;/strong&gt; - Went to the &lt;a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ubl"&gt;UBL committee home page&lt;/a&gt; and browsed &lt;a href="http://docs.oasis-open.org/ubl/os-UBL-2.0/"&gt;UBL 2.0&lt;/a&gt; specs. I have occasionally looked at UBL in the past for inspiration on UML process diagramming so I actually knew pretty much what I would find.&lt;br/&gt;&lt;strong&gt;(10:20 AM)&lt;/strong&gt; - Decided to start with looking at UBL catalogue documents for sourcing and loaded XSD into XML editor. To make sense of the XSD, I decided to have my editor create a document sample....&lt;br/&gt;&lt;strong&gt;(10:30 AM)&lt;/strong&gt; - Starring at 23,000 lines of XML...guess that was not really the right thing to do :-) So I started poking around in the example instance trying to make sense of the various nested XML levels.&lt;br/&gt;&lt;strong&gt;(10:50 AM)&lt;/strong&gt; - MORE COFFEE!!!&lt;br/&gt;&lt;strong&gt;(10:55 AM)&lt;/strong&gt; - Finally I remember having read about UBL customization guidelines for creating UBL subsets! Yep, that sounds a lot of what I need.&lt;br/&gt;&lt;strong&gt;(11:03 AM)&lt;/strong&gt; - Googling...&lt;br/&gt;&lt;br/&gt;Ah:&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;blockquote&gt;if all optional elements in a UBL document type were instantiated, the resulting instance would be extremely verbose. For example, if a UBL Order document contained just one instance of all its possible information entities, that document would contain approximately 800,000 elements and attributes.&lt;/blockquote&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;(From &lt;a href="http://docs.oasis-open.org/ubl/guidelines/UBL2-Customization1prd03.html#_Toc243466459"&gt;guidelines&lt;/a&gt; doc)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-178670280565108736?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/178670280565108736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/in-this-entry.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/178670280565108736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/178670280565108736'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/in-this-entry.html' title=''/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-5447971995731068230</id><published>2010-02-02T11:23:00.000+01:00</published><updated>2010-11-03T10:54:21.110+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac OS X Products'/><title type='text'>Mac OS X Productivity Apps</title><content type='html'>Recently I upgraded to Snow Leopard and naturally this made me review what's in my Applications folder. Here are the more interesting products I use more or less regularly:&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;iWork 09&lt;/strong&gt;&lt;br/&gt;I love iWork since it came out in 2005 (?). I use Pages a lot for personal stuff because client work usually requires true Office compatibility. I always use Keynote though, never Power Point. Keynote is just great. I prefer Excel over Numbers but mostly because I know it better I guess.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Office 2008&lt;/strong&gt;&lt;br/&gt;This is a must have on a consultant's machine and I am mostly satisfied with the Mac OS version. Though Word remains as painful as ever. I love Excel - I think it is the best product Microsoft ever made.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Merlin&lt;/strong&gt;&lt;br/&gt;I am a true lover of this project management application but the occasions where I really need it are rare. I like the look and feel and the millions of export formats. It handles MS Project files nicely.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Nova Mind Platinum&lt;/strong&gt;&lt;br/&gt;The best mind mapping software ever. The Platinum version includes a script writing feature you can use to prepare presentations in a &lt;a href="http://www.beyondbulletpoints.com/"&gt;Beyond Bullet Points&lt;/a&gt; way.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Oxygen XML Editor&lt;/strong&gt;&lt;br/&gt;It took some research to find a nice XML editor for Mac OS X but with Oxygen I found a tool that handles everything you might want to do with XML. I mostly use it for applying XSLTs to some XML and to pretty-print one-line XML files. It is also good for generating example documents from schemas (who understands an XML schema without an example anyway?) and for schema conversions, e.g. RelaxNG to XSD.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Aqua Data Studio&lt;/strong&gt;&lt;br/&gt;Finding a really good database query tool for Mac OS X was even harder than finding an XML editor. What I wanted was a product that would connect to nearly all common databases and would provide at least the functionality of Toad for serious relational work. Aqua Data Studio is excellent and even has a relational diagramming tool and very sophisticated export and import capabilities. Very good for cycles where you need to work on relational data with a set of Unix tools.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Magic Draw Enterprise&lt;/strong&gt;&lt;br/&gt;Magic Draw is an excellent UML tools with code and database engineering support and very nice report generation facilities. I mostly use UML for documentation and I love the database reverse engineering feature to extract relational diagrams from database schemas. It is fast and has very nice look and feel for a Java-on-Mac application. But it is unfortunately not a bargain. NoMagic really does maintain and extend the product frequently so paying for the updates has always been worthwhile for me.&lt;br/&gt;Magic Draw has optional plugins for SysML and DoDAF.&lt;br/&gt; &lt;br/&gt;&lt;strong&gt;Eclipse Classic&lt;/strong&gt;&lt;br/&gt;Trying to stick to 'standard' Eclipse setup with no plugins except for SVN and the gorgeous vi plugin.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Omni Outliner&lt;/strong&gt;&lt;br/&gt;The Max OS X classic outliner. Always open to manage my thoughts. N'uff said.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Omni Focus&lt;/strong&gt;&lt;br/&gt;My current ToDo items application. Though I really want to look at Things.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Screenflow&lt;/strong&gt;&lt;br/&gt;My favorite tools for creating screen casts. I use this to record code walk-throughs with clients or workshops to have something to hand over afterwards.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Parallels Desktop&lt;/strong&gt;&lt;br/&gt;Virtual Machine for running Windows if I have to. I used it a couple of years ago to develop on a client's host. So it was: Remote Desktop over VPN over Parallels - worked quite nicely actually. Nowadays of course, Apple's RDT would do the job.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;BBEdit&lt;/strong&gt;&lt;br/&gt;My editor if I really can't use vi or need to convert between encodings.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Quicksilver&lt;/strong&gt;&lt;br/&gt;Application launcher. Everybody must have Quicksilver, definitely!&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Snippet&lt;/strong&gt;&lt;br/&gt;A little tool for managing code snippets. I often forget about using it, but its a clever thing to have.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;UPDATE:&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Monkey Office&lt;/strong&gt;&lt;br/&gt;After looking at a bunch of accounting software products for the Mac, this is the one I picked.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Adobe CS5&lt;/strong&gt;&lt;br/&gt;It sometimes good to be able to edit designer's work directly, for example to create translations. This saves the roundtrip of having the designer replace the texts. InDesign is an amazing piece of software.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Mondrianum&lt;/strong&gt;&lt;br/&gt;Yesterday, I learned about &lt;a href="http://lithoglyph.com/mondrianum/"&gt;Mondrianum&lt;/a&gt;. This is a color picker that works together with Adobe's &lt;a href="http://kuler.adobe.com"&gt;Kuler&lt;/a&gt;. Difficult to explain what it does - check out for yourself.&lt;br/&gt;&lt;br/&gt;Not worth describing, but there also is EyeTV, Toast, Colloquy, Twitterific, Photoshop, Quicktime Pro, Skype.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-5447971995731068230?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/5447971995731068230/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/02/mac-os-x-productivity-apps.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5447971995731068230'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5447971995731068230'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/02/mac-os-x-productivity-apps.html' title='Mac OS X Productivity Apps'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8988249029374486677</id><published>2010-01-30T00:38:00.000+01:00</published><updated>2010-11-03T10:54:21.112+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Topic Maps'/><title type='text'>Fond Topic Maps Memories</title><content type='html'>Today I have done some &lt;a href="http://www.archive.org"&gt;Web Archeology&lt;/a&gt; and dug up the 2004 version of the &lt;a href="http://www.gooseworks.org/"&gt;GooseWorks.org Web site&lt;/a&gt;. The project was intended to support the original idea of the Topic Maps paradigm as developed by &lt;a href="http://www.coolheads.com"&gt;Steven R. Newcomb&lt;/a&gt; when two camps of ideas started to emerge from the community.&lt;br/&gt;&lt;br/&gt;I remember doing a &lt;a href="http://www.gooseworks.org/downloads/tmtk/"&gt;ridiculous amount of coding&lt;/a&gt; to verify and track Steve's ideas and was joined by &lt;a href="http://thehuntinghouse.com/content/sam-hunting"&gt;Sam Hunting&lt;/a&gt; who evangelized on the various &lt;a href="http://www.balisage.net/"&gt;markup conferences&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Well, that's history, but I thought it might be worthwhile to put the site back online with some of the &lt;a href="http://www.gooseworks.org/downloads/"&gt;source code&lt;/a&gt;. Might also be that I have done so much thinking this week about &lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/5841"&gt;steady-states&lt;/a&gt;, &lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/12101"&gt;bookmarks&lt;/a&gt; and &lt;a href="http://www.w3.org/Provider/Style/URI"&gt;cool URIs&lt;/a&gt; that I felt I had to bring the site back to life.&lt;br/&gt;&lt;br/&gt;In case you are wondering what inspired the name, have a look at the &lt;a href="http://www.infoloom.com/pipermail/topicmapmail/2001q3/002891.html"&gt;posting&lt;/a&gt; that started it all. Besides, it had the cool double-O in it that was said back then to be a guarantee for a site's success :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8988249029374486677?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8988249029374486677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/fond-topic-maps-memories.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8988249029374486677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8988249029374486677'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/fond-topic-maps-memories.html' title='Fond Topic Maps Memories'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1645882356928352724</id><published>2010-01-29T19:43:00.000+01:00</published><updated>2010-11-03T10:54:21.113+01:00</updated><title type='text'>Fun with the Profile Parameter</title><content type='html'>text/csv;profile="http://spec.example.org/profiles/customerdata"&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;http://cgi.ebay.de/Lego-Star-Wars-7656-General-Grievous-Starf-mit-BA-u-OV_W0QQitemZ260542847259QQcmdZViewItemQQptZDE_AllesfürdKind_Spielzeug_Lego?hash=item3ca990591b#ht_500wt_1059&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1645882356928352724?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1645882356928352724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/fun-with-profile-parameter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1645882356928352724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1645882356928352724'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/fun-with-profile-parameter.html' title='Fun with the Profile Parameter'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8928852953493663809</id><published>2010-01-27T10:38:00.000+01:00</published><updated>2010-11-03T10:54:21.115+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>In Fear of Sub-Requests</title><content type='html'>Suppose we design a service that is to provide data about persons, including whom they are linked to. Let's say person representations look like this:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;GET /persons/4/full&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Content-Type: application/vnd.me.person+xml&lt;br/&gt;Cache-Control: no-cache&lt;br/&gt;&lt;br/&gt;&lt;person uri="/persons/4"&gt;&lt;br/&gt;  &lt;name&gt;Karl Heinz&lt;/name&gt;&lt;br/&gt;  &lt;address&gt;Kieler Strasse 7,20556 Hamburg&lt;/address&gt;&lt;br/&gt;  &lt;friends&gt;&lt;br/&gt;    &lt;friend href="/persons/77" /&gt;&lt;br/&gt;    &lt;friend href="/persons/1" /&gt;&lt;br/&gt;    &lt;friend href="/persons/8" /&gt;&lt;br/&gt;    &lt;friend href="/persons/33" /&gt;&lt;br/&gt;    &lt;friend href="/persons/1222" /&gt;&lt;br/&gt;    &lt;friend href="/persons/1" /&gt;&lt;br/&gt;    &lt;friend href="/persons/998" /&gt;&lt;br/&gt;  &lt;/friends&gt;&lt;br/&gt;&lt;/person&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;In addition, the service provides minimal person data that looks like this (note that its time-to-live is longer):&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;GET /persons/4&lt;br/&gt;&lt;br/&gt;200 Ok&lt;br/&gt;Content-Type: application/vnd.me.person+xml&lt;br/&gt;Cache-Control: max-age=3600&lt;br/&gt;&lt;br/&gt;&lt;person uri="/persons/4"&gt;&lt;br/&gt;  &lt;name&gt;Karl Heinz&lt;/name&gt;&lt;br/&gt;  &lt;address&gt;Kieler Strasse 7,20556 Hamburg&lt;/address&gt;&lt;br/&gt;  &lt;link rel="full" href="/persons/4/full"/&gt;&lt;br/&gt;&lt;/person&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Now suppose we define the processing semantics of application/vnd.me.person+xml in such a way that the user agent should follow all the friend links and retrieve the referenced persons' data. Looks like rather bad design due to all the sub-requests, doesn't it?&lt;br/&gt;&lt;br/&gt;On the other hand, nobody complains about HTML pages that link to massive amounts of images and other media.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8928852953493663809?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8928852953493663809/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/in-fear-of-sub-requests.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8928852953493663809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8928852953493663809'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/in-fear-of-sub-requests.html' title='In Fear of Sub-Requests'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-5620472776072655158</id><published>2010-01-26T10:13:00.000+01:00</published><updated>2010-11-03T10:54:21.116+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Contracts'/><title type='text'>4xx Client Error (But Not It's Fault)</title><content type='html'>&lt;a href="http://dret.typepad.com/dretblog/"&gt;Erik&lt;/a&gt; &lt;a href="http://dret.typepad.com/dretblog/2010/01/http-4xx-errors.html"&gt;responds&lt;/a&gt; to &lt;a href="http://www.nordsc.com/blog/?p=142"&gt;4xx Client Error&lt;/a&gt;. He writes:&lt;br/&gt;&lt;br/&gt;&lt;blockquote&gt;"i don't think it appropriate to phrase it like it's the client who necessarily did something wrong when, for example, a 404 is returned. if you follow a URI that was supposed to be persistent and you get a 404 because the server did something wrong, it's quite a stretch to argue that it's your fault. it's pretty clearly not."&lt;br/&gt;&lt;/blockquote&gt;&lt;br/&gt;&lt;br/&gt;I agree that my emphasis on the client doing something wrong wasn't appropriate (but an extreme position is sometimes nice :-). However, I do interpret &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html"&gt;RFC2616&lt;/a&gt; to be emphasizing that the burden is on the client. While it is obviously not the fault of the client if some resource currently has no representation available (404) I would not agree that "the server did something wrong". The server is free to stop providing representations for a resource and the client just has to account for that to happen.&lt;br/&gt;&lt;br/&gt;What is interesting about this is that the conversation between client and server is not considered broken at all because the fact that 4xx errors might occur is part of the contract (and does not indicate a broken contract). This is one of the advantages of a uniform interface with uniform status codes: it can sustain the conversation even when there is a (temporary) gap in expectations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-5620472776072655158?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/5620472776072655158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/4xx-client-error-but-not-it-fault.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5620472776072655158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5620472776072655158'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/4xx-client-error-but-not-it-fault.html' title='4xx Client Error (But Not It&amp;#39;s Fault)'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-5084896909172369711</id><published>2010-01-25T19:51:00.000+01:00</published><updated>2010-11-03T10:54:21.117+01:00</updated><title type='text'>4xx Client Error</title><content type='html'>HTTP is actually quite clear on how decoupled the server is from the client by calling all non-technical errors simply &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4"&gt;Client Errors&lt;/a&gt;. Dang! So simple! 404 - who broke the contract? &lt;strong&gt;The client&lt;/strong&gt;! 406 - who broke the contract? &lt;strong&gt;The client&lt;/strong&gt;! ...&lt;br/&gt;&lt;br/&gt;RFC2616 uses a softer tone though:&lt;br/&gt;&lt;br/&gt;&lt;blockquote&gt;"The 4xx class of status code is intended for cases in which &lt;strong&gt;the client seems to have erred&lt;/strong&gt;."&lt;br/&gt;&lt;/blockquote&gt;&lt;br/&gt;&lt;br/&gt;I guess testing a RESTful system means testing the clients...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-5084896909172369711?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/5084896909172369711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/4xx-client-error.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5084896909172369711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/5084896909172369711'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/4xx-client-error.html' title='4xx Client Error'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1761792998654762184</id><published>2010-01-25T14:20:00.000+01:00</published><updated>2010-11-03T10:54:21.119+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Contracts'/><title type='text'>REST Doesn't Lie</title><content type='html'>Have been &lt;a href="http://iansrobinson.com/2008/04/20/a-contract-vocabulary-part-3/"&gt;reading&lt;/a&gt; &lt;a href="http://www.infoq.com/articles/separation-of-concerns"&gt;about&lt;/a&gt; separation of concerns today and came to think that it might be interesting to shift the angle of looking at service evolution: Instead of asking what aspects of services might change it could actually be useful to ask whether there is anything that a service &lt;em&gt;can&lt;/em&gt; guarantee not to change, no matter what future requirements it might encounter.&lt;br/&gt;&lt;br/&gt;Shifting the point of view revealed a rest constraint that is probably so much taken for granted that it is not talked about very often:&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;blockquote&gt;"The only thing that is required to be static for a resource is the semantics of the mapping, since the semantics is what distinguishes one resource from another."&lt;/blockquote&gt;&lt;br/&gt;&lt;br/&gt;(Section 5.2.2.1 &lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_2_1_1"&gt;Resources and Resource Identifiers&lt;/a&gt; of Roy's dissertation)&lt;br/&gt;&lt;br/&gt;This is a guarantee the server has to make that is actually possible to adhere to because no evolution scenario of a server can possibly force it to change that mapping. The other two things that are not subject to change are (obviously) the uniform interface and the use of descriptive message semantics.&lt;br/&gt;&lt;br/&gt;Besides these three aspects there is nothing in a networked system that servers can guarantee to clients and REST emphasizes that in an incredibly honest way. The client may depend on the above three aspects to remain true for the entire lifetime of a service but must plan for anything else to change.&lt;br/&gt;&lt;br/&gt;What is the take-away? Two things mostly: you are not doing REST unless your system does not adhere to the above and you should exploit the stability of the resource semantics as much as possible in your service design.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1761792998654762184?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1761792998654762184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/rest-doesn-lie.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1761792998654762184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1761792998654762184'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/rest-doesn-lie.html' title='REST Doesn&amp;#39;t Lie'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6476760384799827014</id><published>2010-01-22T15:14:00.000+01:00</published><updated>2010-11-03T10:54:21.120+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>'Completing' application/atomsvc+xml - Part 2</title><content type='html'>In &lt;a href="http://www.nordsc.com/blog/?p=54"&gt;part 1&lt;/a&gt; I have described the reasoning for &lt;em&gt;completing&lt;/em&gt; the AtomPub service document media type; in this part I'll describe some possible extensions that would make AtomPub service documents suitable for describing the initial state of any kind of Web application. Here is, again, the list of aspects that need to be addressed:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;What single resources are there (single resource meaning a resource that is not inherently part of a collection of similar resources like the current temperature or the state of some system's power supply unit).&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;What resources are there that are collections of member resources and what capabilities do they have (for example: do they accept POST submissions?)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;What resources are there that are a set of member resources and provide a generic mechanism to specify subsets (search resources)?&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;What resources are there that do not hold state but merely act as a gateway to some other processing component?&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;(The proposed extension elements below are prefixed with 'appx'.)&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;1. Single resources: allowing &amp;lt;atom:link&amp;gt; inside &amp;lt;app:workspace&amp;gt;&lt;/strong&gt;&lt;br/&gt;Services might expose resources that have special, individual significance to clients. Services need a way to tell the client where such a special resource can be found. For example, a service might expose the 'current state of some technical device' or 'today's featured product' and would need a way to express a link to such a resource that the client could discover. Allowing &amp;lt;atom:link&amp;gt; inside &amp;lt;app:workspace&amp;gt; solves that problem:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;app:service&gt;&lt;br/&gt;  &lt;app:workspace&gt;&lt;br/&gt;    &lt;atom:title&gt;Vehicle Control&lt;/atom:title&gt;&lt;br/&gt;    &lt;atom:link href="/st/device-665" rel="battery-status"&lt;br/&gt;                       title="Battery Status"/&gt;&lt;br/&gt;  &lt;/app:workspace&gt;&lt;br/&gt;&lt;/app:service&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Clients that know the semantics of the 'battery-status' link relation are enabled to find the corresponding resource.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;2. Collection capabilities: introducing an &amp;lt;appx:features&amp;gt; extension&lt;/strong&gt;&lt;br/&gt;AtomPub service documents are able to express what categories the members of a given collection have. This can be used by clients to discover collections based on their member's categories. However, in some situations services need to be able to distinguish collections by capability or abstract behavior in order to express domain semantics that go beyond standard HTTP semantics. Overloading categories for this purpose is not the right solution.&lt;br/&gt;The introduction of an extension element inside &amp;lt;app:collection&amp;gt; that enables the service to describe that a collection exhibits a certain capability or abstract behavior addresses this issue:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;app:service&gt;&lt;br/&gt;  &lt;app:workspace&gt;&lt;br/&gt;    &lt;atom:title&gt;Image Conversion Service&lt;/atom:title&gt;&lt;br/&gt;    &lt;app:collection href="/converters/thumbnails"&gt;&lt;br/&gt;       &lt;atom:title&gt;To Thumbnail Converter&lt;/atom:title&gt;&lt;br/&gt;       &lt;appx:features&gt;&lt;br/&gt;         &lt;appx:feature ref="thumbnails-creator"&gt;&lt;br/&gt;       &lt;/appx:features&gt;&lt;br/&gt;      &lt;app:accept&gt;image/jpeg,image/gif&lt;/app:accept&gt;&lt;br/&gt;    &lt;/app:collection&gt;&lt;br/&gt;    &lt;app:collection href="/converters/sharpener"&gt;&lt;br/&gt;       &lt;atom:title&gt;Sharpener&lt;/atom:title&gt;&lt;br/&gt;       &lt;appx:features&gt;&lt;br/&gt;         &lt;appx:feature ref="sharpener"&gt;&lt;br/&gt;       &lt;/appx:features&gt;&lt;br/&gt;       &lt;app:accept&gt;image/jpeg,image/gif&lt;/app:accept&gt;&lt;br/&gt;    &lt;/app:collection&gt;&lt;br/&gt;  &lt;/app:workspace&gt;&lt;br/&gt;&lt;/app:service&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;The above service document describes two collections that each exhibit a special behavior that is significant to the client. Based on the desired conversion to be performed on a submitted image it can choose the appropriate collection. This is a scenario where the category or media type of the submitted representation is orthogonal to the capability of the collection.&lt;br/&gt;(This extension element is based on the original &lt;a href="http://tools.ietf.org/html/draft-snell-atompub-feature-12"&gt;draft-snell-atompub-feature Internet draft&lt;/a&gt; by &lt;a href="http://www.snellspace.com"&gt;James Snell&lt;/a&gt;).&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;3. Search: introducing an &amp;lt;appx:search&amp;gt; extension&lt;/strong&gt;&lt;br/&gt;Despite search being an almost ubiquitous requirement AtomPub does not currently support the description of search capabilities of a service. Support for search can be added to AtomPub service documents by introducing an extension element that enables the service to describe accepted parameters, format and media type of the search resource.&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;app:service&gt;&lt;br/&gt;  &lt;app:workspace&gt;&lt;br/&gt;    &lt;atom:title&gt;Product Search&lt;/atom:title&gt;&lt;br/&gt;    &lt;appx:search href="/products/search" method="GET"&gt;&lt;br/&gt;       &lt;appx:parameters&gt;&lt;br/&gt;         &lt;appx:parameter localname="q" name="http://www.example.org/specs/params/searchTerms" min="1" max="1"/&gt;&lt;br/&gt;         &lt;appx:parameter localname="category" name="http://www.example.org/specs/params/category" min="0" max="*"/&gt;&lt;br/&gt;       &lt;/appx:parameters&gt;&lt;br/&gt;    &lt;/appx:search&gt;&lt;br/&gt;  &lt;/app:workspace&gt;&lt;br/&gt;&lt;/app:service&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Clients can process this form and construct the query string for the GET request. There are several other aspects defined by the &lt;a href="http://www.opensearch.org"&gt;OpenSearch specification&lt;/a&gt; that would make a lot of sense to add here.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;4. Processors: introducing &amp;lt;appx:processor&amp;gt; extension&lt;/strong&gt;&lt;br/&gt;Occasionally services expose resources that merely act as a gateway to some other data submission processing component. Such resources do not exhibit the POST-as-append semantic of AtomPub collections and therefore using &amp;lt;app:collection&amp;gt; to describe such resources is not appropriate. Instead, an extension element is introduced to describe processor resource capabilities:&lt;br/&gt;&lt;br/&gt;&lt;pre lang="xml"&gt;&lt;br/&gt;&lt;app:service&gt;&lt;br/&gt;  &lt;app:workspace&gt;&lt;br/&gt;    &lt;atom:title&gt;Customer Relationship Services&lt;/atom:title&gt;&lt;br/&gt;    &lt;appx:processor href="/channels/punch-out"&gt;&lt;br/&gt;       &lt;atom:title&gt;Catalogue 'Punch Out' Fax&lt;/atom:title&gt;&lt;br/&gt;       &lt;appx:features&gt;&lt;br/&gt;         &lt;appx:feature ref="punch-out"&gt;&lt;br/&gt;       &lt;/appx:features&gt;&lt;br/&gt;       &lt;app:accept&gt;application/vnd.foo.procurement-catalogue+xml&lt;/app:accept&gt;&lt;br/&gt;    &lt;/appx:processor&gt;&lt;br/&gt;  &lt;/app:workspace&gt;&lt;br/&gt;&lt;/app:service&gt;&lt;br/&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;The above processor description tells clients that there is a data submission accepting process at /channels/punch-out that features the abstract behavior 'punch-out' and accepts application/vnd.foo.procurement-catalogue+xml request bodies.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Note&lt;/strong&gt;: I am not entirely convinced of the necessity of &amp;lt;appx:processor&amp;gt; because any data processing resource could always create a resource upon submission that represents the processing request. That way &amp;lt;app:collection&amp;gt; could be used instead. The members of the collection could simply be HTML documents that describe the processing request. It would also be possible to just not implement GET for the AtomPub collection resource and return 200 Ok (without Location header) for the data submission. This is not fully in sync with AtomPub's description of the operations, but an HTTP client must be prepared to handle any return code anyway.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br/&gt;I doubt that the above will be deemed relevant to the Atom Publishing Protocol, but I think it would be very useful to have a general service description document format. Especially so in enterprise IT contexts, where the number of services is high and a uniform means of service description simplifies matters considerably. In fact, I have needed something like the above in every project so far and used almost all of the extensions above in my latest one.&lt;br/&gt;&lt;br/&gt;The rationale really is that there is in my opinion no possible requirement for service descriptions that cannot be addressed by the above generic format. Since application/atomsvc+xml already covers most of it, why not combine it with the extensions to form a new media type?&lt;br/&gt;&lt;br/&gt;When I find the time I'll probably submit this as a request to register &lt;em&gt;application/service+xml&lt;/em&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6476760384799827014?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6476760384799827014/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/applicationatomsvcxml-part-2.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6476760384799827014'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6476760384799827014'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/applicationatomsvcxml-part-2.html' title='&amp;#39;Completing&amp;#39; application/atomsvc+xml - Part 2'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-185605461297087080</id><published>2010-01-22T09:58:00.000+01:00</published><updated>2010-11-03T10:54:21.123+01:00</updated><title type='text'>Why if(status == 200) Is Not Enough</title><content type='html'>In &lt;a href="http://www.ibm.com/developerworks/web/library/wa-aj-gmt/"&gt;another Developer Works article&lt;/a&gt; I read yesterday, Bruce Sun provides a co&lt;a href="http://www.ibm.com/developerworks/web/library/wa-aj-gmt/#listing10"&gt;de snippet&lt;/a&gt; that acts as an HTTP client to a service&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-185605461297087080?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/185605461297087080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/why-ifstatus-200-is-not-enough.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/185605461297087080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/185605461297087080'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/why-ifstatus-200-is-not-enough.html' title='Why if(status == 200) Is Not Enough'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6264308630599578787</id><published>2010-01-21T23:22:00.000+01:00</published><updated>2010-11-03T10:54:21.124+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST Design Mistakes'/><title type='text'>REST Design Mistake with Apache Wink</title><content type='html'>Just came across &lt;a href="http://www.ibm.com/developerworks/web/library/wa-apachewink1/index.html"&gt;an article on service implementation&lt;/a&gt; with &lt;a href="http://incubator.apache.org/wink/"&gt;Apache Wink&lt;/a&gt; by Vishnu Vettrivel. While it is primarily covering the service implementation aspects, it also has a section on RESTful design that too easily creates a wrong understanding of how a RESTful service would have to be designed.&lt;br/&gt;&lt;br/&gt;Given that REST has entered the &lt;a href="http://en.wikipedia.org/wiki/Hype_cycle"&gt;hype cycle&lt;/a&gt; it happens too often now, that actually unRESTful design is promoted. It is probably time to spend more energy on preventing that REST will be doomed before enough adopters have indeed realized and, more importantly, experienced the benefits. REST done badly might actually cause more harm than WS-* done well, so lets be wary!&lt;br/&gt;&lt;br/&gt;What is wrong about the article? Three things mostly:&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;&lt;strong&gt;Likely violation of the hypermedia constraint&lt;/strong&gt;: the article proposes a URI structure but fails to make clear that this knowledge must not leak to the client developer but that the client should discover the appropriate links or forms at runtime. Coupling on the URI structure must be avoided to allow the server to control (and change) its own URI space without the risk of breaking clients.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;strong&gt;Misplaced authentication information&lt;/strong&gt;: the proposed design places user name and password as parameters into the URI while they should be send to the server using standard HTTP authentication mechanisms. This can negatively impact caching since caches understand the special meaning of the Authenticate header. In the worst case, a public cache might keep a representation that should only be visible to an authenticated client.&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;&lt;strong&gt;Limited visibility&lt;/strong&gt;: the article proposes the use of application/json but fails to make clear that this causes coupling on the out-of-band knowledge of the actual JSON structure being used.&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;I am aware that RESTful design is not at the heart of this article, but we should make sure that whoever reads what we write does not walk away with a wrong impression of what a RESTful design is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6264308630599578787?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6264308630599578787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/rest-design-mistake-with-apache-wink.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6264308630599578787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6264308630599578787'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/rest-design-mistake-with-apache-wink.html' title='REST Design Mistake with Apache Wink'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-7056413284562874641</id><published>2010-01-21T18:37:00.000+01:00</published><updated>2010-11-03T10:54:21.126+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>'Completing' application/atomsvc+xml - Part 1</title><content type='html'>The Atom Publishing Protocol specifies the media type application/atomsvc+xml for service description documents. At first glance the things that Atom Publishing Protocol service documents can describe seem quite specific. However, from a more general point of view, AtomPub service documents are really just describing what collections of resources are being made available by a given service and which are the capabilities they have. AtomPub service documents are describing something about a service that applies to any kind of service, not only AtomPub services.&lt;br/&gt;&lt;br/&gt;We might as well turn the line of thought around and ask: "What are the aspects that make sense to be described for any kind of service (not only AtomPub services)?"&lt;br/&gt;&lt;br/&gt;Now, it only makes sense to describe something about a particular service that is specific to that service and therefore needs to be told to the client at runtime. The only thing in a RESTful service that is specific to a particular service is through witch resources it provides access to the application data and associated processes it manages and how those resources reference each other to constitute the state machine that the client can follow. Anything else is design time information described by hypermedia specifications that apply to a broader context than a single service.&lt;br/&gt;&lt;br/&gt;A second aspect that is important in this context is that it is (of course) not desirable to describe the &lt;em&gt;whole&lt;/em&gt; set of resources and their relationships because this would lead to unnecessary coupling. Clients just need to be put into the initial application state by downloading the service description document. The description of this initial state is what service documents are necessary for.&lt;br/&gt;&lt;br/&gt;The original question can be rephrased to: "What are the aspects that constitute the initial state of a RESTful application without introducing any particular domain semantics?".&lt;br/&gt;&lt;br/&gt;In my opinion, there are four aspects that apply to any RESTful application and can therefore be considered general:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;What single resources are there (&lt;em&gt;single resource&lt;/em&gt; meaning a resource that is not inherently part of a collection of similar resources like the current temperature or the state of some system's power supply unit).&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;What resources are there that are collections of member resources and what capabilities do they have (for example: do they accept POST submissions?)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;What resources are there that are a set of member resources and provide a generic mechanism to specify subsets (search resources)?&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;What resources are there that do not hold state but merely act as a gateway to some other processing component?&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;br/&gt;[Side note: you might want to look at &lt;a href="http://www.markbaker.ca"&gt;Mark Baker&lt;/a&gt;'s &lt;a href="http://www.markbaker.ca/2001/09/draft-baker-http-resource-state-model-01.txt"&gt;Abstract Model for HTTP Resource State&lt;/a&gt;; it is somewhat related.]&lt;br/&gt;&lt;br/&gt;With the premise that the items above are general enough to apply to any kind of Web application (service) wouldn't it make sense to have a service document format that is capable of expressing information along the lines of those items?&lt;br/&gt;&lt;br/&gt;I think it does and I also think (and this is the motivation for this posting) that application/atomsvc+xml service documents already cover a substantial part. Which might, after all, be the reason why AtomPub seems such a nice fit in many scenarios.&lt;br/&gt;&lt;br/&gt;In part 2 of this posting I will present a couple of extensions to application/atomsvc+xml that make this service document media type 'complete' in the sense of being able to express items 1-4 above. This will cover:&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;Allowing &amp;lt;atom:link&amp;gt; in &amp;lt;app:workspace&amp;gt; elements to express 'single resources'&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;A &lt;a href="http://tools.ietf.org/html/draft-snell-atompub-feature-12"&gt;&amp;lt;feature&amp;gt; extension&lt;/a&gt; to express abstract capability or behavior of a collection&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;A &amp;lt;search&amp;gt; element to express search resources (much like &lt;a href="http://www.opensearch.org"&gt;OpenSearch&lt;/a&gt; does)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;A &amp;lt;processor&amp;gt; element to express resources that accept data submission but are not a collection in the AtomPub sense.&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;I am pretty convinced that such a format would be able to represent the initial state of any RESTful application and since AtomPub provides all the plumbing already it is probably worth the effort.&lt;br/&gt;&lt;br/&gt;Read &lt;a href="http://www.nordsc.com/blog/?p=80"&gt;part 2&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-7056413284562874641?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/7056413284562874641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/applicationatomsvcxml-part-1.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7056413284562874641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7056413284562874641'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/applicationatomsvcxml-part-1.html' title='&amp;#39;Completing&amp;#39; application/atomsvc+xml - Part 1'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6349997067752134934</id><published>2010-01-21T02:10:00.000+01:00</published><updated>2010-11-03T10:54:21.128+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SOAP'/><title type='text'>The Protocol Hammer</title><content type='html'>It's not news, but &lt;a href="http://tech.groups.yahoo.com/group/service-orientated-architecture/message/14076"&gt;Anne's statement&lt;/a&gt; just popped out when I scanned through the archives:&lt;br/&gt;&lt;blockquote&gt;"If I knew what I know now back in 2000, I would have pushed for a RESTful registry with free-form search, and such a beast would have been a lot more valuable than UDDI. But we had this really spiffy, state-of-the-art protocol hammer called SOAP, and we saw everything as a nail."&lt;/blockquote&gt;&lt;br/&gt;Reminds me that &lt;a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm"&gt;REST&lt;/a&gt; officially turns 10 this year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6349997067752134934?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6349997067752134934/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/protocol-hammer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6349997067752134934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6349997067752134934'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/protocol-hammer.html' title='The Protocol Hammer'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-3065192145942103135</id><published>2010-01-20T14:04:00.000+01:00</published><updated>2010-11-03T10:54:21.129+01:00</updated><title type='text'>Test</title><content type='html'>Das ist ein Bild so wie es sein solll&lt;br/&gt;&lt;br/&gt;&lt;a href="http://www.nordsc.com/blog/wp-content/uploads/2010/01/test1.jpg"&gt;&lt;img class="alignnone size-full wp-image-47" title="test" src="http://www.nordsc.com/blog/wp-content/uploads/2010/01/test1.jpg" alt="" width="300" height="236" /&gt;&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;Und das ist gut&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-3065192145942103135?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/3065192145942103135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/test.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3065192145942103135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3065192145942103135'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/test.html' title='Test'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8031020391109707627</id><published>2010-01-08T13:08:00.001+01:00</published><updated>2010-11-03T10:54:21.131+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Service Types'/><title type='text'>Service Type Specifications II</title><content type='html'>&lt;strong&gt;UPDATE&lt;/strong&gt;: My thinking around this issue has &lt;a href="http://www.nordsc.com/blog/?p=382"&gt;evolved&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Wow, this question was much harder to get straight than I expected:&lt;br/&gt;&lt;br/&gt;&lt;em&gt;What constitutes the specification of a service type?&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;First things first, though! In order to provide a principled answer to that question, another one needs to be answered before:&lt;br/&gt;&lt;br/&gt;&lt;em&gt;What is the purpose of a service type specification?&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Purpose of Service Type Specifications&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;1. Service type specifications provide the information client developers need to implement a client for services of the described type. If you hand the service type specification to a developer she should be able to know exactly what to do and what to reasonably expect from any instance of that service type. There should be no further knowledge required (except for following any included references, for example, to media type specifications, of course).&lt;br/&gt;&lt;br/&gt;2. Service type specifications provide the information necessary for implementing instances of the specified service type. There should not be any further information required except for implementation specific details behind the service boundary of course.&lt;br/&gt;&lt;br/&gt;3. Service type specifications provide the information service owners and maintainers need in order to understand in which way the server can evolve without breaking clients. This is redundant with 2. but mentioning it explicitly emphasizes where exactly the contract is established between client and server owners. Anything that is not specified in the service type specification or referenced material is not part of the contract and constitutes no obligation by either party.&lt;br/&gt;&lt;br/&gt;4. Service type specifications enable service discovery by type. Clients that wish to interact with a certain kind of service can use the information provided by the service type specification to detect when they see a service that is of the desired type. The necessary information should be available as a response to the published service URI either by analyzing the set of initial transitions (goals) provided by the service or by looking at the service document's media type (see below).&lt;br/&gt;&lt;br/&gt;Having laid out the purposes of a service type specification, we can now make principled decisions about what should be part of a service type specification.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Elements of Service Type Specifications&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Here is the short answer (rationale follows below):&lt;br/&gt;&lt;br/&gt;&lt;em&gt;Service Type Specifications define the set of hypermedia specifications (media types, link relations, etc.)  used by the service and information about the minimal initial set of available transitions (goals).&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;The latter can optionally be expressed as a media type, too (a service type specific service document type), which simplifies the definition to 'a set of media types' but leads to the creation of a new media type for a given kind of service.&lt;br/&gt;&lt;br/&gt;The essential aspect of the above definition is that the client needs to know what the media types are it needs to understand in order to interact with the service.&lt;br/&gt;&lt;br/&gt;So, why is that?&lt;br/&gt;&lt;br/&gt;The ideal situation would be to say nothing about the service type at all, just agree on a set of media types that make sense to be understood in general and implement all or any of them in the clients as desired. The problem with this approach is that it does not address purpose 1. above; a client developer would not have any clue what a service is doing or how to interact with it. There would not be any notion of a service type at all; just individual hypermedia semantics (media types, link relations etc.).&lt;br/&gt;&lt;br/&gt;But even if the client developer was provided with some means of a service type description (in the form of a dedicated service media type or a set of initial transitions) - see purpose 4. above - there would still be no way for the client developer to have any clue what can be done with the service beyond the initial transitions. Knowing the set of media types provides that clue.&lt;br/&gt;&lt;br/&gt;The issue of guiding the service developer (purpose 2.) is addressed because the service type tells the service developer exactly what media types etc. are available to him to solve the given implementation task.&lt;br/&gt;&lt;br/&gt;Purpose 3. above is addressed by the fact that it is not possible to remove a hypermedia specification from the specified set without incompatibly changing the semantics of the service type. Service owners are therefore free to evolve the service by adding hypermedia specifications (or extending extensible ones) but may not remove any.&lt;br/&gt;&lt;br/&gt;The purpose of discovery (4. above) can be addressed by using a generic service description media type such as Atom Service documents (application/atomsrv+xml) and describing a minimal set of available resources. For example, an ITIL-conforming help desk service type could be specified as providing at least three collections (identified by categories) containing and accepting submissions of Incidents, Problems and Change Requests. Clients (including service registry crawlers) would know they come across an instance of that 'ITIL helpdesk service' when they see an Atom Service with the specified collections.&lt;br/&gt;&lt;br/&gt;Alternatively, a new service document media type could be minted (e.g. application/helpdesksrv+xml) to identify the service type. The format of that type would be defined to provide links to the necessary resources. This leads to simpler discovery/registry mechanism but also might cause explosion of media types.&lt;br/&gt;&lt;br/&gt;Using a combination of both might actually be best, such as application/atomsrv+xml;profile=helpdesk.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8031020391109707627?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8031020391109707627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2010/01/service-type-specifications-ii_08.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8031020391109707627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8031020391109707627'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2010/01/service-type-specifications-ii_08.html' title='Service Type Specifications II'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-3711708010172662574</id><published>2009-12-07T11:58:00.001+01:00</published><updated>2010-11-03T10:54:21.133+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Service Types'/><title type='text'>Service Type Specifications</title><content type='html'>Over the last weeks I've been busy with finding a suitable approach towards REST Web services descriptions. Not quite there yet, but close! Here is my list of essential aspects a service type specification must address:&lt;br/&gt;&lt;ol&gt;&lt;br/&gt;	&lt;li&gt;Overall purpose of the service (aka the realized business process role)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;What client goals does the service enable (aka protocol operations)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;When can the client expect certain goals to be available (aka partial ordering of application states)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;What does the client have to do to 'execute' a certain goal (aka hypermedia semantics)&lt;/li&gt;&lt;br/&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-3711708010172662574?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/3711708010172662574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/12/service-type-specifications_07.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3711708010172662574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3711708010172662574'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/12/service-type-specifications_07.html' title='Service Type Specifications'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8792730688165552104</id><published>2009-11-27T11:29:00.002+01:00</published><updated>2010-11-03T10:54:21.134+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Separation of Concerns'/><title type='text'>Separation of Concerns and Replication</title><content type='html'>In an integration scenario that involves the replication of items from one system (the master) to another (the slave) the direction of the communication is an interesting issue.&lt;br /&gt;&lt;br /&gt;First, there is the question, whether the initial creation of a replicated item in the slave should be performed by a request from the master to the slave or by a request from the slave to the master. The former will often be chosen when there is a business rule involved that should trigger the replication (e.g. replicate all employees in the slave system whose contract ends in 6 months). The latter is more likely to be used in a scenario where the slave replicates all new items in the master, in other words, where the slave keeps the overall set of items in sync.&lt;br /&gt;&lt;br /&gt;Second there is the question how updates of the items in the master are made available in the slave. This is the classic distinction between polling and publish/subscribe: Should the master notify the client of updates or should the slave poll for updates?&lt;br /&gt;&lt;br /&gt;In addition, there is sometimes a desire to notify the master about changes the slave makes to the replicated items. The intention of this scenario is not the bidirectional synchronization of master and slave but reflects the master's interest in any changes the slave makes.&lt;br /&gt;&lt;br /&gt;What is the guiding principle to make an informed design decision regarding the direction of communication in such a replication scenario? The answer is &lt;i&gt;separation of concerns &lt;/i&gt;with the goal of simplicity and avoiding unnecessary coupling. This leads to the question which of the systems should for which communication play the server role and which one should play the client role?&lt;br /&gt;&lt;br /&gt;Every communication is initiated to achieve some goal and the correct separation of concerns puts the component that acts to achieve the goal into the client role and the other component into the server role.&lt;br /&gt;&lt;br /&gt;Applied to the above scenarios this means that for initial replication and subsequent updates the slave system should act as a client and the master should act as a server. All the necessary resources to be provided by the sever (e.g. providing list of all items that match a business rule) can be derived.&lt;br /&gt;&lt;br /&gt;Applied to the scenario where the master is interested in updates from the slave it means that the master should act as the client because it is the master that has the goal (the slave does not care at all). This leads to certain resources that need to be exposed by the slave.&lt;br /&gt;&lt;br /&gt;I have seen at least three production systems that had this issue and all of them did it wrong and would have greatly benefited in terms of simplicity and loose coupling from following the above principled design path.&lt;br /&gt;&lt;br /&gt;Related is Roy's post &lt;a href="http://roy.gbiv.com/untangled/2008/paper-tigers-and-hidden-dragons"&gt;Paper tigers and hidden dragons&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8792730688165552104?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8792730688165552104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/11/separation-of-concerns-and-replication_27.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8792730688165552104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8792730688165552104'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/11/separation-of-concerns-and-replication_27.html' title='Separation of Concerns and Replication'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8100189498792024652</id><published>2009-11-26T01:01:00.002+01:00</published><updated>2010-11-03T10:54:21.136+01:00</updated><title type='text'>History of Fragment Identifiers</title><content type='html'>Everything you ever wanted to know about fragment identifiers - an &lt;a href="http://lists.w3.org/Archives/Public/www-tag/2002Jul/0253.html"&gt;in-depth coverage&lt;/a&gt; by Roy back in 2002.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8100189498792024652?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8100189498792024652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/11/history-of-fragment-identifiers_26.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8100189498792024652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8100189498792024652'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/11/history-of-fragment-identifiers_26.html' title='History of Fragment Identifiers'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1962131404122283391</id><published>2009-11-25T21:44:00.002+01:00</published><updated>2010-11-03T10:54:21.137+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTTP Howto'/><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>300 and 406 Response Bodies</title><content type='html'>Reading through some older postings, I came across &lt;a href="http://lists.w3.org/Archives/Public/w3c-dist-auth/1997JulSep/0054.html"&gt;this&lt;/a&gt; by Roy:&lt;br/&gt;&lt;pre style="font-family: monospace; color: black; background-color: #ffffff; white-space: pre-wrap; padding: .5em;"&gt;That is why we have a WebDAV working group.  Both the 300 and 406 response bodies were left unspecified because the intention was that they be specified by a group that actually had time to study the problem in detail and come up with a [hopefully] better solution than some off-the-cuff invention of mine.  It was one of the WebDAV to-do items, last time I checked.&lt;/pre&gt;&lt;br/&gt;Has this ever been done? Maybe it is time to create some standard 300 and 406 response media type?&lt;br/&gt;&lt;div&gt;UPDATE: Umm, should have searched a bit more I guess: &lt;a href="http://tools.ietf.org/html/rfc2295"&gt;RFC2295&lt;/a&gt;. What is left is to tell clients to look for Alternates headers in 300 and 406 responses.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1962131404122283391?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1962131404122283391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/11/300-and-406-response-bodies.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1962131404122283391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1962131404122283391'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/11/300-and-406-response-bodies.html' title='300 and 406 Response Bodies'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-463297625225107525</id><published>2009-11-17T00:25:00.001+01:00</published><updated>2010-11-03T10:54:21.138+01:00</updated><title type='text'>ESB Decoupling Capabilities and the Elegance of REST</title><content type='html'>In his presentation "&lt;a href="http://www.infoq.com/presentations/Enterprise-Service-Bus"&gt;The Role of the ESB&lt;/a&gt;" &lt;a href="http://wmrichards.com/"&gt;Mark Richards&lt;/a&gt; makes the point that the most significant capability of an ESB is that it enables the separation of "Business Services" from "Service Implementations" (at 00:11:25). "Business Services", he says, "are the ones that make sense to the business" while "the implementation service [...] is the one we actually code". As an example he contrasts "PlaceTrade" and "saveTradeOrder()" and talks about how PlaceTrade is much more stable than saveTradeOrder() because the former is a business semantic and not an implementation detail.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While it is truly astonishing what amount of tooling and complexity the slide conveys in order to provide a business service 'PlaceTrade' it is something else that struck me as being really interesting:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is obvious that, in order to provide a 'PlaceTrade' service, there needs to be implementation details that should not be conveyed to the user of 'PlaceTrade'. (According to Richards, SOA wonderfully solves that problem by using an ESB that translates the business service into an implementation service call. Can't help it...&lt;i&gt;enterprisey&lt;/i&gt; comes to mind...) &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;REST takes a different approach: in a RESTful system, the implementation details that correspond to the translation of 'PlaceTrade' to 'saveTradeOrder()' manifest themselves in the form of the resource model of a service (the actual resources the service chooses to make available). This is a direct consequence of realizing business functionality through a uniform interface.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Interestingly, in a RESTful system, clients are inherently decoupled from the services' resource models - the contract between client and server is expressed solely through hypermedia specifications, independent of any actual service implementation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In other words: SOA makes use of ESBs to achieve a decoupling that is already inherent in REST per design.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;POST /trades&lt;br /&gt;Content-Type: application/trade-order&lt;br /&gt;&lt;br /&gt;&amp;lt;trade-order&amp;gt;&lt;br /&gt;....&lt;br /&gt;&amp;lt;/trade-order&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-463297625225107525?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/463297625225107525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/11/esb-decoupling-capabilities-and_17.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/463297625225107525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/463297625225107525'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/11/esb-decoupling-capabilities-and_17.html' title='ESB Decoupling Capabilities and the Elegance of REST'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-3009209931025419631</id><published>2009-11-05T14:19:00.001+01:00</published><updated>2010-11-03T10:54:21.140+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Contracts'/><category scheme='http://www.blogger.com/atom/ns#' term='Service Types'/><title type='text'>Service Descriptions and Legal Contracts</title><content type='html'>The intermediate result of the thoughts triggered by the recent interchange on the SOA list are &lt;a href="http://tech.groups.yahoo.com/group/rest-discuss/message/13996"&gt;here&lt;/a&gt;. Comments welcome!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-3009209931025419631?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/3009209931025419631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/11/service-descriptions-and-legal_05.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3009209931025419631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3009209931025419631'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/11/service-descriptions-and-legal_05.html' title='Service Descriptions and Legal Contracts'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6638077115695145577</id><published>2009-11-03T13:22:00.001+01:00</published><updated>2010-11-03T10:54:21.141+01:00</updated><title type='text'>Formal Contracts</title><content type='html'>&lt;div&gt;When clients in a RESTful system are not ultimately driven by a human then the expectations they make about the resource model of the services and the available representation formats will inevitably be manifested in the client side code to some extend.&lt;/div&gt;&lt;div&gt;While the client developer can go  along way in limiting the assumptions made about the server at some point the client code just needs to explicitly assume that there is for example a 'place order' state traversal (aka 'link' or 'form') when interacting with a service were you can order stuff. The client can plan for various ways in which the server could express the link or form but ultimately the client code will contain some form of orderProcessorUri = clientLib.lookupUri(...expression to find order processor URI...).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If the traversal option cannot be found the client will break without a possibility to automatically react. This is where a human user would change the online store or call the hotline.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://service-architecture.blogspot.com/"&gt;Steve Jones&lt;/a&gt; &lt;a href="http://tech.groups.yahoo.com/group/service-orientated-architecture/message/13909"&gt;is&lt;/a&gt; &lt;a href="http://tech.groups.yahoo.com/group/service-orientated-architecture/message/13910"&gt;concerned&lt;/a&gt; &lt;a href="http://tech.groups.yahoo.com/group/service-orientated-architecture/message/13920"&gt;about&lt;/a&gt; the development process related- and legal implications of the lack of a formal means for documenting such implicit contracts created between client and server once the client manifests its assumptions in its own code or configuration. I think he is making some valid (and too often ignored) points.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have been working on related questions during the past weeks and currently see the following issues:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;While the freedom that is usually (deliberately) given to servers in Internet specifications improves evolvability it is not a sufficient basis for establishing legal contracts between service consumers and service providers. If you make a serious investment into implementing a client to some service then &lt;a href="http://www.ietf.org/rfc/rfc2119.txt"&gt;RFC 2119&lt;/a&gt;'s SHOULD is probably not the best contractual basis.&lt;/li&gt;&lt;li&gt;If a service makes use of a variety of media types, extensions, link relations, categories, etc. then how would one express this in a formal way?&lt;/li&gt;&lt;li&gt;If a client is dependent on the presence of some Atom extension in Atom entry documents for example, how could the service provider state that they are committed to providing that extension?&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is important though to emphasize the general goal of maintaining the flexibility induced by REST's constraints and at the same time to make explicit and to formalize the inevitable coupling that occurs when non-human clients interact with services.&lt;/div&gt;&lt;div&gt;This is important not only for development-process and legal matters but also for IT governance and Service Management issues and critical for the adoption of REST inside the enterprise.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6638077115695145577?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6638077115695145577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/11/formal-contracts_03.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6638077115695145577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6638077115695145577'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/11/formal-contracts_03.html' title='Formal Contracts'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1899769312708411094</id><published>2009-10-27T20:24:00.001+01:00</published><updated>2010-11-03T10:54:21.143+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Contracts'/><title type='text'>Hidden Contracts and Governance</title><content type='html'>&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;In a RESTful system the contract between client and server is expressed solely in the form of hypermedia specifications[1]. On the Web this works fine, because there is usually always a human being involved that can act as the ultimate arbiter of semantics when things need to be decided that happen not to be covered by the involved hypermedia specifications.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;Examples:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;1. When I want to buy a book, what hypermedia is telling me that www.amazon.de is a place to go?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;2. When the Amazon site is not reachable, how do I find out where else I could buy a book?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;3.How do I know what 'buying a book' means and what the basic sequence of operations is that need to be executed in order to achieve the overall goal?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;4. How do I figure out, what the new appropriate sequence of operations is should Amazon significantly change its understanding of the flow of a book purchase?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;All of the above are ultimately solved by a human being in the case of the Web and usually don't cause any trouble. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;3. is particularly interesting because the fact that no hypermedia specification even touches that question reveals that there is a very high level, common sense contract in operation between human clients and some Web applications.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;4. is also interesting because economic sense will usually keep e.g. a book seller from changing the flow of operations in a way that causes the potential buyer to not being able to buy anymore.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;How does all this relate to IT governance? &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial, serif;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;When one applies REST (HTTP that is in practice) in an enterprise IT context, these hidden contracts matter because they either need to be covered by hypermedia specifications (e.g. for the discovery/equivalence examples 1. and 2.) or at least need to be made explicit so they become manageable in an IT governance sense.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;Example 3. relates to the general question of how types of services (e.g. 'procurement seller role' or 'repository') can be expressed to provide guidance to client developers regarding the intended sequence of operations.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;Example 4 relates to the question of how change can be managed not of the pertaining hypermedia specifications (this is easy!) but of their composition (which is what effectively forms the service type).&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;Besides being able to frame the problem and ask the questions I do not yet have definitive answers - comments and thoughts are very welcome.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; min-height: 14px; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span&gt;&lt;br/&gt;lass="Apple-style-span" style="font-size:medium;"&amp;gt;[1] The term 'hypermedia specification' is meant as a general expression for specifications of media types, media type extensions, link relations and 'little' things like category definitions (used for example by Atom and NewsML2). &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial, serif;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial, serif;"&gt;(Also &lt;a href="https://www.xing.com/net/rest/rest-governance-428636/hidden-contracts-25491172/25491172/#25491172"&gt;posted&lt;/a&gt; in the &lt;a href="https://www.xing.com/net/rest"&gt;XING REST Group&lt;/a&gt;)&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;p style="font: 12px Helvetica; margin: 0;"&gt;&lt;span style="font-family: arial;"&gt;&lt;span style="font-size: medium;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;br/&gt;&lt;br/&gt;&lt;div&gt;&lt;span style="font-family: arial, serif;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1899769312708411094?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1899769312708411094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/10/hidden-contracts-and-governance.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1899769312708411094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1899769312708411094'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/10/hidden-contracts-and-governance.html' title='Hidden Contracts and Governance'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-7136632824692582291</id><published>2009-10-26T15:18:00.001+01:00</published><updated>2010-11-03T10:54:21.145+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Books'/><title type='text'>Taylor, Medvidović, Dashofy. 2010. Software Architecure</title><content type='html'>The &lt;a href="http://www.softwarearchitecturebook.com/"&gt;book&lt;/a&gt; just arrived and I think it is one of those worth an in-depth study!&lt;br/&gt;&lt;div&gt;I like the caution note on page 421:&lt;/div&gt;&lt;br/&gt;&lt;div&gt;"Numerous Web sites and books purport to characterize or exemplify REST principles. The reader should be very cautious, as many sources misrepresent or mischaracterize REST."&lt;/div&gt;&lt;br/&gt;&lt;div&gt;Sadly so..&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-7136632824692582291?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/7136632824692582291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/10/taylor-medvidovic-dashofy-2010-software.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7136632824692582291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/7136632824692582291'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/10/taylor-medvidovic-dashofy-2010-software.html' title='Taylor, Medvidović, Dashofy. 2010. Software Architecure'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6335579299978838071</id><published>2009-10-10T19:03:00.001+02:00</published><updated>2010-11-03T10:54:21.146+01:00</updated><title type='text'>Product Modeling at W3C</title><content type='html'>&lt;a href="http://www.w3.org/2005/Incubator/w3pm/XGR-w3pm-20091008/"&gt;This&lt;/a&gt; seems sort of interesting and probably has some potential to be used in Web architecture-based procurement collaborations. Is there any serious industry involvement in this?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I wonder if OWL and friends will eventually obfuscate the real goal; wouldn't a decent media type be a better way to approach this?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6335579299978838071?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6335579299978838071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/10/product-modeling-at-w3c_10.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6335579299978838071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6335579299978838071'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/10/product-modeling-at-w3c_10.html' title='Product Modeling at W3C'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-3608036488343289536</id><published>2009-10-06T14:55:00.001+02:00</published><updated>2010-11-03T10:54:21.147+01:00</updated><title type='text'>Please use 'Hypermedia Constraint'!!</title><content type='html'>The hit count of &lt;a href="http://twitter.com/#search?q=HATEOAS"&gt;this&lt;/a&gt; should go to zero! &lt;a href="http://twitter.com/#search?q=hypermedia%20constraint"&gt;This&lt;/a&gt; should skyrocket instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-3608036488343289536?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/3608036488343289536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/10/please-use-constraint.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3608036488343289536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3608036488343289536'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/10/please-use-constraint.html' title='Please use &amp;#39;Hypermedia Constraint&amp;#39;!!'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-6439552300218439923</id><published>2009-10-01T08:35:00.001+02:00</published><updated>2010-11-03T10:54:21.148+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>Formal Hypermedia Contexts</title><content type='html'>Formally, a &lt;a href="http://www.nordsc.com/blog/?p=6"&gt;hypermedia context&lt;/a&gt; can be understood as a conjunction of predicates that evaluates to true or false for a given URI. The predicates can be expressed as one of the following:&lt;br/&gt;&lt;div&gt;&lt;br/&gt;&lt;ul&gt;&lt;br/&gt;	&lt;li&gt;unary link, e.g service(x)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;binary relationship, e.g. edit-media(u1,x)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;pattern match on representation of x, e.g. r-match( xpathExpr , x)&lt;/li&gt;&lt;br/&gt;	&lt;li&gt;pattern match on occurrance of x in representation, e.g match( xpathExpr , x)&lt;/li&gt;&lt;br/&gt;&lt;/ul&gt;&lt;br/&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;Logical sentences build from such predicates can be evaluated against the current state of the client to either test if a given URI matches the denoted context or to find all URIs known to the client that match the predicate conjunction.&lt;/div&gt;&lt;br/&gt;&lt;div&gt;The next step will be to express the operations that are currently stated in the form of prose in hypermedia specifications in terms of the above predicate conjunctions and HTTP operations. For example could AtomPub's 'create entry' operation be expressed as the combination of the predicate conjunction match( '/service/workspace/collection@href',x) and POST. Where the match predicate evaluates to true for any URI x that is found as the value of the XPath expression.&lt;/div&gt;&lt;br/&gt;&lt;div&gt;This needs more precision of course, but it's a start.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-6439552300218439923?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/6439552300218439923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/10/formal-hypermedia-contexts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6439552300218439923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/6439552300218439923'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/10/formal-hypermedia-contexts.html' title='Formal Hypermedia Contexts'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-8591851239502860029</id><published>2009-09-30T19:48:00.001+02:00</published><updated>2010-11-03T10:54:21.151+01:00</updated><title type='text'>RFC 5545</title><content type='html'>&lt;a href="http://tools.ietf.org/html/rfc5545"&gt;iCalendar&lt;/a&gt; is now an IETF Proposed Standards Protocol (superseedes &lt;a href="http://tools.ietf.org/html/rfc2445"&gt;RFC 2445&lt;/a&gt;). Does anyone know whether this is just fixing things or whether there are additional semantics that increase the expressiveness?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-8591851239502860029?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/8591851239502860029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/09/rfc-5545_30.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8591851239502860029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/8591851239502860029'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/09/rfc-5545_30.html' title='RFC 5545'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-1965630563716296684</id><published>2009-09-30T07:52:00.001+02:00</published><updated>2010-11-03T10:54:21.152+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>Hypermedia Context</title><content type='html'>&lt;span style="font-family: arial;"&gt;Descriptions of REST interfaces often use the notion of types when talking about the exposed resources. &lt;/span&gt;&lt;a href="http://tools.ietf.org/html/rfc5023"&gt;&lt;span style="font-family: arial;"&gt;The Atom Publishing Protocol&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: arial;"&gt; for example includes &lt;/span&gt;&lt;a href="http://tools.ietf.org/html/rfc5023#section-4.2"&gt;&lt;span style="font-family: arial;"&gt;a section&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: arial;"&gt; that provides a resource classification. Such classifications are not against the RESTfulness of an interface as long as the classes are expressed in terms of the knowledge a client has acquired about a resource. The Atom Publishing Protocol for example states that "a Resource whose IRI is listed in a Collection is called a Member Resource". This is a valid classification from the point of view of its RESTfulness.&lt;/span&gt;&lt;br/&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;In order to emphasize that such classification can only be done in terms of the acquired application state of the client I suggest the term "hypermedia context" instead of "classification". REST interface descriptions could then for example state: "The hypermedia context of a resource is called Member if its URI is listed in a collection". There is probably also value in distinguishing the client-acquired knowledge about a resource from the context used in the specification by calling the former &lt;/span&gt;&lt;em&gt;&lt;span style="font-family: arial;"&gt;acquired hypermedia context&lt;/span&gt;&lt;/em&gt;&lt;span style="font-family: arial;"&gt; or just &lt;/span&gt;&lt;em&gt;&lt;span style="font-family: arial;"&gt;hypermedia context&lt;/span&gt;&lt;/em&gt;&lt;span style="font-family: arial;"&gt; and the latter &lt;/span&gt;&lt;em&gt;&lt;span style="font-family: arial;"&gt;named hypermedia context.&lt;/span&gt;&lt;/em&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;I can also see possibilities to formalize hypermedia contexts along the lines of predicates, for example as an AND combination of known links, appearance of links in received hypermedia and (XPath-)matches on the representations of resources. &lt;/span&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;span style="font-family: arial, serif;"&gt;&lt;br/&gt;&lt;/span&gt;&lt;/div&gt;&lt;br/&gt;&lt;div&gt;&lt;span style="font-family: arial;"&gt;But I'll address that in a follow up.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-1965630563716296684?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/1965630563716296684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/09/hypermedia-context_30.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1965630563716296684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/1965630563716296684'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/09/hypermedia-context_30.html' title='Hypermedia Context'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-4359938642332378750</id><published>2009-09-29T14:16:00.001+02:00</published><updated>2010-11-03T10:54:21.153+01:00</updated><title type='text'>Location Header Semantics</title><content type='html'>&lt;div&gt;Depending on the response's HTTP status the Location header has slightly different impact on the client's application state. The following table summarizes what I extracted from the HTTP spec.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;table border="1" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top"&gt;Status&lt;/td&gt;&lt;td&gt;Semantic&lt;/td&gt;&lt;td&gt;Comment&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;201 Created&lt;/td&gt;&lt;td&gt;URI of created resource&lt;/td&gt;&lt;td&gt;Client is notified that a new resource has been created an can dereference the URI to see what has been created, e.g. to verify its expectations.&lt;br /&gt;ETag can be used to provide current ETag of created resource&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;204 No Content&lt;/td&gt;&lt;td&gt;URI of created resource(?)&lt;/td&gt;&lt;td&gt;&lt;a href="http://lists.w3.org/Archives/Public/ietf-http-wg/2009JulSep/0873.html"&gt;Clarification pending&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;300 Multiple Choices&lt;/td&gt;&lt;td&gt;URI of server's preferred variant&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;301 Moved Permanently&lt;/td&gt;&lt;td&gt;New permanent URI&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;302 Found&lt;/td&gt;&lt;td&gt;Temporay URI to use for requests to the intended resource&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;303 See Other&lt;/td&gt;&lt;td&gt;Response to the POST request is found at another URI&lt;/td&gt;&lt;td&gt;If client follows redirect and if the client already knows the target resource the 303 works as a notification that the previous POST has changed the target resource.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;305 Use Proxy&lt;/td&gt;&lt;td&gt;URI of proxy to use for the request.&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;307 Moved Temporarily&lt;/td&gt;&lt;td&gt;Temporary URI to use for requests to this resource.&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;201 and 303 provide the grounds for interesting generic client behavior. About the nature of 305 I am not sure yet but the server's ability to redirect a client to an intermediary smells interesting. &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-4359938642332378750?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/4359938642332378750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/09/location-header-semantics_29.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4359938642332378750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/4359938642332378750'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/09/location-header-semantics_29.html' title='Location Header Semantics'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-3368349484099429681</id><published>2009-09-18T18:19:00.001+02:00</published><updated>2010-11-03T10:54:21.155+01:00</updated><title type='text'>REST Interface Implementation Design</title><content type='html'>It occurred to me today that there is a subtle design artifact that sits in between the specification of a REST API and its actual implementation. Let me try to explain what I mean:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The specification of a REST API consists of the media types, extensions and link semantics that a potential client must understand to be able to meaningfully interact with the API. The combination of &lt;a href="http://www.ietf.org/rfc/rfc4287.txt"&gt;Atom&lt;/a&gt; and the &lt;a href="http://www.ietf.org/rfc/rfc5023.txt"&gt;Atom Publishing Protocol&lt;/a&gt; is a good example of this.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The implementation of a REST API maps the 'back end layer' to a number of resources that provide access to the 'back end layer' in terms of the semantics of the REST API.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This looks like the expected differentiation between interface and implementation, much like you implement an OO interface with a class.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Interestingly, in the case of REST there is a third design artifact that resides somewhere in the middle between interface and implementation: the design decision of what resource are actually exposed and which of the interface semantics are actually used in which circumstances. It could be argued that this decision is part of the implementation, but by distinguishing the two it becomes clearer that there are many potential ways how different systems can manifest a given REST interface. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A class that implements an OO interface will always just implement the methods that constitute the interface, no decisions besides the actual implementation, no surprises. When implementing an Atom Publishing Protocol service, there is an unlimited number of ways to organize feeds and add links to feed or entry documents. One can even build two entirely different APP facades around a given back end but still use the same code to map back end resources (general sense) to feed and entry documents.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When REST API specifications define what resources a client will find on the server side and what type they have then this is an indication that the specification (wrongly) includes the server-side design artifact described above. Such specification elements must be removed from the API to make it RESTful.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-3368349484099429681?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/3368349484099429681/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/09/rest-interface-implementation-design_18.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3368349484099429681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/3368349484099429681'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/09/rest-interface-implementation-design_18.html' title='REST Interface Implementation Design'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6187843820292518013.post-687578158711260830</id><published>2009-09-17T10:41:00.001+02:00</published><updated>2010-11-03T10:54:21.156+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hypermedia Design'/><title type='text'>Parameters are Link Relation Specific</title><content type='html'>I used to view REST APIs to be constituted by media types, extensions, link relations and parameters (query-, form- and URI template parameters). Reading through &lt;a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven"&gt;Roy's checklist&lt;/a&gt; again today I realized that he suggests a superior approach: By making the parameters link relation specific the problem that parameters are usually not bound to a name space goes away and there is one less class of design artifacts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6187843820292518013-687578158711260830?l=algermissen.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://algermissen.blogspot.com/feeds/687578158711260830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://algermissen.blogspot.com/2009/09/parameters-are-link-relation-specific_17.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/687578158711260830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6187843820292518013/posts/default/687578158711260830'/><link rel='alternate' type='text/html' href='http://algermissen.blogspot.com/2009/09/parameters-are-link-relation-specific_17.html' title='Parameters are Link Relation Specific'/><author><name>Jan Algermissen</name><uri>http://www.blogger.com/profile/09496801860218501437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='31' height='32' src='http://4.bp.blogspot.com/_qvBX_KaH6Bg/SsLxoFcrWdI/AAAAAAAAAAM/rcXrTimKiS0/S220/ja_100.jpg'/></author><thr:total>0</thr:total></entry></feed>
