<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en-US" xml:base="http://iansrobinson.com/wp-atom.php">
	<title type="text">iansrobinson.com</title>
	<subtitle type="text">Ian Robinson's Blog</subtitle>

	<updated>2012-04-24T07:02:16Z</updated>

	<link rel="alternate" type="text/html" href="http://iansrobinson.com" />
	<id>http://iansrobinson.com/feed/atom/</id>
	

	<generator uri="http://wordpress.org/" version="3.5.1">WordPress</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/iansrobinson" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="iansrobinson" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">iansrobinson</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[Progressive .NET Tutorial]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2011/08/02/progressive-net-tutorial/" />
		<id>http://iansrobinson.com/?p=511</id>
		<updated>2011-08-02T16:47:21Z</updated>
		<published>2011-08-02T16:47:21Z</published>
		<category scheme="http://iansrobinson.com" term="Events" /><category scheme="http://iansrobinson.com" term="REST" />		<summary type="html"><![CDATA[On September 7th I&#8217;ll be running a half-day tutorial on building RESTful Web services as part of the Skills Matter and London .NET User Group&#8217;s Progressive .NET Tutorials. This will be a very hands-on tutorial. Over the course of three and a half hours we&#8217;ll build a hypermedia-driven service and client in .NET using the [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2011/08/02/progressive-net-tutorial/"><![CDATA[<p>On September 7th I&#8217;ll be running a half-day tutorial on building RESTful Web services as part of the Skills Matter and London .NET User Group&#8217;s <a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-tutorials-2011/cs-2275" title="Progressive .NET Tutorials">Progressive .NET Tutorials</a>.</p>

<p>This will be a very hands-on tutorial. Over the course of three and a half hours we&#8217;ll build a hypermedia-driven service and client in .NET using the new <a href="http://wcf.codeplex.com" title="WCF Web APIs">WCF Web APIs</a>. The subject matter hearkens back to a favourite subject of mine, <a href="http://jaoo.dk/aarhus-2009/presentation/Hydras+and+Hypermedia" title="Hydras and Hypermedia">Hydras and Hypermedia</a>, for the application we&#8217;ll build will be a simple text-based pick-your-path-to-adventure game.</p>

<p>This isn&#8217;t a tutorial on games design, however. Despite the non-enterprisey subject matter, the tutorial serves to illustrate how machine clients and services can cooperate to achieve a useful application goal. Business application analogies lurk around every corner and surprise you with every encounter.</p>

<p>The tutorial comprises three exercises. With each exercise you&#8217;ll have to fix a number of broken unit and functional tests. Bit by bit, you&#8217;ll build a working application:</p>

<ul>
<li><strong>Exercise 1:</strong> Here we implement the server resources that make up the dungeon &#8211; the chambers, tunnels and caves in which our daring client will venture.</li>
<li><strong>Exercise 2:</strong> Next we build a crafty client that can discover a path through the dungeon. By the end of the exercise, the client ought to be able to navigate the dungeon from entrance to exit.</li>
<li><strong>Exercise 3:</strong> Last, we add an element of danger, populating the dungeon with encounters (more resources) that the client must overcome before it achieves its application goal.</li>
</ul>

<p>Along the way you&#8217;ll learn about:</p>

<ul>
<li>The Atom Syndication Format</li>
<li>&#8220;What if&#8221; client-side intelligence</li>
<li>The client as arbiter of application state</li>
<li>Hypermedia controls: links, link relations and forms</li>
<li>DRY URIs</li>
</ul>

<p>So come and join me for what promises to be an entertaining hack-n-slash workshop. Attendees should be familiar with C# and unit testing, and have some knowledge of HTTP.</p>

<p>Full details and registration for the entire event can be found <a href="http://skillsmatter.com/event/open-source-dot-net/progressive-dot-net-tutorials-2011/cs-2275" title="Progressive .NET Tutorials">here</a>.</p>]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2011/08/02/progressive-net-tutorial/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2011/08/02/progressive-net-tutorial/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[The Power of the Daleks (and Neo4j)]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2011/07/11/the-power-of-the-daleks-and-neo4j/" />
		<id>http://iansrobinson.com/?p=351</id>
		<updated>2012-04-24T07:01:28Z</updated>
		<published>2011-07-11T01:35:37Z</published>
		<category scheme="http://iansrobinson.com" term="Neo4j" />		<summary type="html"><![CDATA[Jim Webber and I have been busy these last few months writing a tutorial for Neo4j. As we did with REST in Practice, we&#8217;ve chosen an example domain that falls a little outside the enterprise norm. With REST in Practice we chose the everyday world of the coffee shop; this time round, we&#8217;ve gone for [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2011/07/11/the-power-of-the-daleks-and-neo4j/"><![CDATA[<p><a href="http://jim.webber.name" title="Jim Webber's blog">Jim Webber</a> and I have been busy these last few months writing a <a href="https://github.com/jimwebber/neo4j-tutorial" title="Neo4j tutorial">tutorial</a> for <a href="http://neo4j.org" title="Neo4j">Neo4j</a>. As we did with <a href="http://restinpractice.com" title="REST in Practice"><em>REST in Practice</em></a>, we&#8217;ve chosen an example domain that falls a little outside the enterprise norm. With <em>REST in Practice</em> we chose the everyday world of the coffee shop; this time round, we&#8217;ve gone for the grand old universe of <a href="http://bbc.co.uk/doctorwho" title="Doctor Who">Doctor Who</a>.</p>

<p>As we&#8217;ve worked on the tutorial, we&#8217;ve built up a Doctor Who data model that shows how Neo4j can be used to address several different data and domain concerns. For example, part of the dataset includes timeline data, comprising seasons, stories and episodes; elsewhere we&#8217;ve social network-like data, with characters connected to one another through being companions, allies or enemies of the Doctor. It&#8217;s a messy and densely-connected dataset &#8211; much like the data you might find in a real-world enterprise. Some of it is of high quality, some of it is lacking in detail. And for every seeming invariant in the domain, there&#8217;s an awkward exception &#8211; again, much like the real world. For example, each incarnation of the Doctor has been played by one actor, except the first, who was originally played by William Hartnell, and then later by Richard Hurdnall, who reprised the tetchy first incarnation some years after William Hartnell&#8217;s death for the twenty-fifth anniversary story, <em>The Five Doctors</em>. Each episode has a title; at least, they did when the series first began, in 1963, and they do today. But towards the end of the third season, the original series stopped assigning individual episode titles (in the original series, stories typically took place over several episodes); a story&#8217;s episodes were simply labelled Part 1, Part 2, etc. And so on.</p>

<h2>The Dalek Props</h2>

<img alt="Dalek prop" src="http://www.projectdalek.com/uploads/gallery_uploads/1299139376/gallery_377_18_30629.jpg" title="dalek-prop" class="alignleft" width="292" height="450" style="margin-right:15px;margin-top:5px"/>

<p>The earliest alien monsters to appear in Doctor Who, the Daleks have long held a fascination for the British viewing public, and for the enquiring minds of Doctor Who fandom. In 2002, Jon Green began researching the history of the Dalek props created for the original series, which ran from 1963 to 1988. Jon was later joined by a second researcher, Gav, and the result of their hard work is the wonderful <a href="http://www.dalek6388.co.uk/" title="Dalek 6388">Dalek 6388</a>.

<p>Recently, I imported some of this Dalek research into our Doctor Who database. From the wealth of detail available on Dalek 6388 I chose to focus on the ways the different prop parts were reused in different stories.</p>

<p>Each episode or story featuring the Daleks made use of one or more Dalek props. Each prop came in two parts: the top half, called the <em>shoulders</em>, and the bottom half, called the <em>skirt</em>.  These parts were handmade, and as a result there were many differences between them: the hemisphere spacing, collars, slats, eyestalks, and gun boxes in particular varied in subtle but noticeable ways. Reconstructing the history of the props has been largely a matter of identifying specific parts in screenshots and photos based on these visual clues.</p>

<p>Over time, the different shoulders and skirts were mixed and matched. For example, the shoulders originally belonging to <strong>Dalek 1</strong>, one of the props created for the very first Dalek story, <em>The Daleks</em>, were later paired with the skirt belonging to <strong>Dalek 5</strong> for the story <em>Day of the Daleks</em>. This composite prop is known as <strong>Dalek One-5</strong>. A couple of seasons later, the shoulders were paired with the skirt belonging to <strong>Dalek 7</strong> for the Daleks&#8217; last outing with Jon Pertwee&#8217;s Doctor, <em>Death to the Daleks</em>. This composite prop is known as <strong>Dalek One-7</strong>.</p>

<h2>Structuring the Data</h2>

<p>With the details from Dalek 6388 added to our dataset we now have something that resembles a supply chain traceability scheme &#8211; another excellent use for Neo4j. Here&#8217;s how some of that data is structured (click the image for a closeup view):</p>

<p><a href="http://iansrobinson.com/blog/wp-content/uploads/2011/07/dalek-props.png"><img src="http://iansrobinson.com/wp-content/uploads/2011/07/dalek-props-small.png" alt="Dalek props" title="dalek-props-small" width="500" height="317" class="size-full wp-image-395" /></a></p>

<p>The screenshot above shows some of the Dalek prop data as viewed in <a href="http://wiki.neo4j.org/content/Neoclipse_Guide" title="Neoclipse guide">Neoclipse</a>. Neoclipse allows you to view, create and edit nodes, as well as search any indexes you&#8217;ve created for your store. Neo4j&#8217;s browser-based Webadmin tool also includes a visualisation tab for viewing a database running in server mode.</p>

<p>The screenshot above show three of the stories in which the Daleks appeared: <em>The Daleks</em>, <em>The Dalek Invasion of Earth</em> and <em>The Power of the Daleks</em>. (They&#8217;ve appeared in many more stories &#8211; the view here shows only a fraction of the data we have. Even here I&#8217;ve only shown full details of the props for one of the stories, <em>The Power of the Daleks</em>. Portions of the data associated with the other two stories are then included to show how the data is interconnected.)</p>

<p>Below each story node is a node representing the group of Dalek props used in that story. I&#8217;ve chosen to create these group nodes because there is potentially other data to be included at the group level. For example, each story was assigned a budget for building or maintaining the props used in that story. Moreover, in the research, the voice artists and operators responsible for bringing the Daleks to life are not associated with individual props but with the group as a whole (the details of the voice artists and operators are not, however, currently in our dataset). Hence the Dalek props group nodes <code>USED_IN</code> each story.</p>

<p>Focusing now on the props used in <em>The Power of the Daleks</em>, we can see that four props appeared in the story: <strong>Dalek 1</strong>, <strong>Dalek 2</strong>, <strong>Dalek 7</strong>, and <strong>Dalek Six-5</strong>. <strong>Daleks 1</strong> and <strong>2</strong> also appeared in the two earlier stories, <em>The Daleks</em> and <em>The Dalek Invasion of Earth</em> (together with some other props not shown here), as well as in several other stories not shown in the screenshot. <strong>Daleks 7</strong> and <strong>Six-5</strong> are here not associated with any other stories, but in the full dataset, <strong>Dalek 7</strong> is shown to have appeared in two other stores, <em>The Evil of the Daleks</em> and <em>The Chase</em>, while <strong>Dalek Six-5</strong> appeared in four other stories following its debut in the <em>The Power of the Daleks</em>.<p>

<p><strong>Dalek Six-5</strong> is one of those composite props I mentioned previously. It is <code>COMPOSED_OF</code> shoulders whose <code>ORIGINAL_PROP</code> was <strong>Dalek 6</strong>, and a skirt originally made for <strong>Dalek 5</strong>. The shoulders, as the graph in the screenshot shows, appeared as part of at least one other composite prop, <strong>Dalek Six-7</strong>, where they were paired with the skirt belonging to <strong>Dalek 7</strong>, which also appears in <em>The Power of the Daleks</em>. <strong>Dalek Six-5</strong>&#8216;s skirt, whose <code>ORIGINAL_PROP</code> was <strong>Dalek 5</strong>, was at some other time paired with the shoulders from <strong>Dalek 1</strong> to create the composite prop <strong>Dalek One-5</strong>. (To find out which story <strong>Dalek One-5</strong> appeared in, all we&#8217;d have to do is expand the graph beyond the nodes shown here.)<p>

<h2>Querying the Data</h2>

<p>The Dalek prop data captures many of the significant domain concepts and relationships described in the <a href="http://www.dalek6388.co.uk/" title="Dalek 6388">Dalek 6388</a> research. Once we&#8217;d built the dataset, I set about asking it some tricky questions. At the top of my list of pressing questions was this one: what&#8217;s the hardest working Dalek prop part in showbiz? That is, which of those shoulders and skirts has appeared in more stories than any other part?</p>

<p>Neo4j offers several different ways to query a graph. There&#8217;s the <a href="http://api.neo4j.org/current/" title="Core API Java docs">Core API</a>, which allows you to deal imperatively with nodes and relationships, and the original <a href="http://components.neo4j.org/neo4j/1.4.M06/apidocs/org/neo4j/graphdb/Node.html#traverse%28org.neo4j.graphdb.Traverser.Order,%20org.neo4j.graphdb.StopEvaluator,%20org.neo4j.graphdb.ReturnableEvaluator,%20org.neo4j.graphdb.RelationshipType,%20org.neo4j.graphdb.Direction,%20org.neo4j.graphdb.RelationshipType,%20org.neo4j.graphdb.Direction%29" title="Traversal API Java docs">Traverser API</a>, which offers a slightly more declarative route into a graph. For more sophisticated traversals there&#8217;s the <a href="http://wiki.neo4j.org/content/Traversal_Framework" title="Traversal Framework guide">Traversal Framework</a>, which, being more powerful than the Traversal API, has a slightly steeper learning curve. For querying the server there&#8217;s the <a href="http://docs.neo4j.org/chunked/stable/rest-api.html" title="REST API guide">REST API</a>. Next, there&#8217;s <a href="https://github.com/tinkerpop/gremlin/wiki" title="Gremlin wiki">Gremlin</a>, a powerful graph traversal language with a plugin for Neo4j, and the <a href="http://components.neo4j.org/neo4j-graph-matching/snapshot/" title="Pattern Matching guide">Pattern Matching</a> library, which is like a regex language for graphs. And finally, introduced in the latest 1.4 milestones, there&#8217;s <a href="http://docs.neo4j.org/chunked/stable/cypher-query-lang.html" title="Cypher documentation">Cypher</a>, a new declarative graph pattern matching language &#8211; a SQL for graphs.</p>

<p>In the rest of this post we&#8217;ll look at three different ways of figuring out which was the hardest working Dalek prop part. In the first example we&#8217;ll look at the Traversal Framework. In the next we&#8217;ll use the Pattern Matching library. Finally, we&#8217;ll use Cypher.</p>

<p>There&#8217;s quite a bit of code here. If you haven&#8217;t the patience to wade through it all, do just one thing: <a href="#cypher">go look</a> at the Cypher query. It&#8217;s a thing of Dalek-like precision.</p>

<h3>Traversal Framework</h3>
<p>Here&#8217;s what the query to find the hardest working Dalek prop part looks like using the Traversal Framework:</p>
<pre><code>@Test
public void shouldFindTheHardestWorkingPropsUsingTraversalFramework() {
&nbsp;&nbsp;Node theDaleks = database.index().forNodes(&quot;species&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;.get(&quot;species&quot;, &quot;Dalek&quot;).getSingle();

&nbsp;&nbsp;Traverser traverser = Traversal.description()
&nbsp;&nbsp;&nbsp;&nbsp;.relationships(Rels.APPEARED_IN, Direction.OUTGOING)
&nbsp;&nbsp;&nbsp;&nbsp;.relationships(Rels.USED_IN, Direction.INCOMING)
&nbsp;&nbsp;&nbsp;&nbsp;.relationships(Rels.MEMBER_OF, Direction.INCOMING)
&nbsp;&nbsp;&nbsp;&nbsp;.relationships(Rels.COMPOSED_OF, Direction.OUTGOING)
&nbsp;&nbsp;&nbsp;&nbsp;.relationships(Rels.ORIGINAL_PROP, Direction.OUTGOING)
&nbsp;&nbsp;&nbsp;&nbsp;.depthFirst()
&nbsp;&nbsp;&nbsp;&nbsp;.evaluator(new Evaluator() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@Override
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Evaluation evaluate(Path path) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (path.lastRelationship() != null &amp;&amp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path.lastRelationship().isType(Rels.ORIGINAL_PROP)){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Evaluation.INCLUDE_AND_PRUNE;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Evaluation.EXCLUDE_AND_CONTINUE;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;})
&nbsp;&nbsp;&nbsp;&nbsp;.uniqueness(Uniqueness.NONE)
&nbsp;&nbsp;&nbsp;&nbsp;.traverse(theDaleks);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;assertHardestWorkingPropParts(getSortedResults(traverser),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 1 shoulder&quot;, 12,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 5 skirt&quot;, 12,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 6 shoulder&quot;, 12);
}</code></pre>

<p>This example shows an idiomatic usage of the Neo4j Traversal Framework. First, we lookup a starting node for the traversal in an index. In this instance, we look up the Dalek species node. Then we build a traversal description and execute the traversal from this starting node. The traversal crawls the subgraph below the starting node. With each node that it visits, it calls the <code>evaluate()</code> method on the custom evaluator supplied with the description. This method determines whether the traverser is positioned over a node of interest (in this case, an original prop node). If it is, the traverser returns the path to this node to the calling code, and then begins a new travesal further up the subtree. If it isn&#8217;t a node of interest, the traverser continues deeper into the subgraph.</p>

<p>The description specifies the types of relationship we&#8217;re prepared to follow, and their direction. Every relationship in Neo4j has a type label and a direction. The direction helps provide semantic clarity when dealing with asymmetric relationships between nodes. While a relationship between two nodes is always directed &#8211; it has a start node, a direction, and an end node &#8211; a traverser can be programmed to follow either an <code>INCOMING</code> or an <code>OUTGOING</code> relationship, and even to ignore the direction entirely (using <code>Direction.BOTH</code>).</p>

<p>Note that we&#8217;ve specified that the traversal proceed depth first. This means that from the Dalek species node it will strike out on a depth first hunt for an original prop, following the first <code>APPEARED_IN</code> relationship to an episode and then searching the nodes below that episode. Once it has found a first matching original prop, the traverser returns the path to the prop to the calling code (<code>INCLUDE_AND_PRUNE</code>), and then moves successively back <em>up</em> that path, trying alternate branches, until it works its way all the way back to the species node, from where it tries the next <code>APPEARED_IN</code> relationship.<p>

<p>Here&#8217;s the route the traverser takes from the starting Dalek species node through all the nodes below <em>The Power of the Daleks</em>:</p>

<ul>
<li>(Dalek)-[:APPEARED_IN]->(The Power of the Daleks)<-[:USED_IN]-(Daleks)<-[:MEMBER_OF]-(Dalek 7)-[:COMPOSED_OF]->(skirt)-[:ORIGINAL_PROP]->(Dalek 7) <strong>INCLUDE_AND_PRUNE</strong></li>
<li>-[:COMPOSED_OF]->(shoulder)-[:ORIGINAL_PROP]->(Dalek 7) <strong>INCLUDE_AND_PRUNE</strong></li>
<li><-[:MEMBER_OF]-(Dalek Six-5)-[:COMPOSED_OF]->(skirt)-[:ORIGINAL_PROP]->(Dalek 5) <strong>INCLUDE_AND_PRUNE</strong></li>
<li>-[:COMPOSED_OF]->(shoulder)-[:ORIGINAL_PROP]->(Dalek 6) <strong>INCLUDE_AND_PRUNE</strong></li>
<li><-[:MEMBER_OF]-(Dalek 2)-[:COMPOSED_OF]->(skirt)-[:ORIGINAL_PROP]->(Dalek 2) <strong>INCLUDE_AND_PRUNE</strong></li>
<li>-[:COMPOSED_OF]->(shoulder)-[:ORIGINAL_PROP]->(Dalek 2) <strong>INCLUDE_AND_PRUNE</strong></li>
<li><-[:MEMBER_OF]-(Dalek 1)-[:COMPOSED_OF]->(skirt)-[:ORIGINAL_PROP]->(Dalek 1) <strong>INCLUDE_AND_PRUNE</strong></li>
<li>-[:COMPOSED_OF]->(shoulder)-[:ORIGINAL_PROP]->(Dalek 1) <strong>INCLUDE_AND_PRUNE</strong></li>
</ul>

<p>Now that the traverser is back at the Dalek species node, it tries the next <code>APPEARED_IN</code> relationship:</p>

<ul>
<li>-[:APPEARED_IN]->(The Dalek Invasion of Earth)<-[:USED_IN]-(Daleks)<-[:MEMBER_OF]-(Dalek 6)-[:COMPOSED_OF]->(skirt)-[:ORIGINAL_PROP]->(Dalek 6) <strong>INCLUDE_AND_PRUNE</strong></li>
<li>-[:COMPOSED_OF]->(shoulder)-[:ORIGINAL_PROP]->(Dalek 6) <strong>INCLUDE_AND_PRUNE</strong></li>
</ul>

<p>And so on.</p>

<p>When it&#8217;s run, our traverser will return all the paths from the Dalek species node to the original props nodes associated with each prop part. Each path contains all the details of the nodes and relationships along that path, starting with the Dalek species node and ending with the original prop node, with the relevant episode and prop part nodes somewhere in between.</p>

<p>By itself, the traverser result doesn&#8217;t tell us which prop part has been used the most; for that, we need to do some accumulation. To generate the counted and sorted results, our code calls <code>getSortedResults()</code>, which is simply a helper method that delegates to a <code>ResultsAssembler</code> instance. This <code>ResultsAssembler</code> is responsible for accumulating the results for each prop part.</p>

<p>Here&#8217;s the <code>getSortedResults()</code> method:</p>

<pre><code>private Map&lt;String, Integer&gt; getSortedResults(Traverser traverser) {
&nbsp;&nbsp;Map&lt;String, Integer&gt; results = new ResultsAssembler&lt;Path&gt;(traverser)
&nbsp;&nbsp;&nbsp;&nbsp;.sortResults(new PathAccessor());
&nbsp;&nbsp;return results;
}</code></pre>

<p>And here is the code for the <code>ResultsAssembler</code>:</p>

<pre><code>public interface QueryResultAccessor&lt;T&gt; {
&nbsp;&nbsp;String getOriginalProp(T queryResult);
&nbsp;&nbsp;String getPart(T queryResult);
}
&nbsp;&nbsp;
public class ResultsAssembler&lt;T&gt;{
&nbsp;&nbsp;private final Iterable&lt;T&gt; queryResults;

&nbsp;&nbsp;public ResultsAssembler(Iterable&lt;T&gt; queryResults) {
&nbsp;&nbsp;&nbsp;&nbsp;super();
&nbsp;&nbsp;&nbsp;&nbsp;this.queryResults = queryResults;
&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;public Map&lt;String, Integer&gt; sortResults(QueryResultAccessor&lt;T&gt; accessor){
&nbsp;&nbsp;&nbsp;&nbsp;Map&lt;String, Integer&gt; unsortedResults = new HashMap&lt;String, Integer&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;for (T queryResult : queryResults){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String originalProp = accessor.getOriginalProp(queryResult);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String part = accessor.getPart(queryResult);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String key = originalProp + &quot; &quot; + part;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!unsortedResults.containsKey(key)){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsortedResults.put(key, 0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;unsortedResults.put(key, unsortedResults.get(key) + 1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Comparator&lt;String&gt; valueComparator = Ordering.natural()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.onResultOf(Functions.forMap(unsortedResults))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.reverse().compound(Ordering.natural());
&nbsp;&nbsp;&nbsp;&nbsp;return ImmutableSortedMap.copyOf(unsortedResults, valueComparator);
&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
}</code></pre>

<p>The <code>ResultsAssembler</code> builds a map of prop part keys and episode count values. The assembler uses a <code>QueryResultAccessor</code> to retrieve the original prop name and prop part from a query result. Here the query result is a path, but when we get round to the next example, which uses the Pattern Matching library, it&#8217;s a pattern match object. Hence the generic parameters.</p>

<p>Here&#8217;s the <code>PathAccessor</code> we use to access the original prop name and prop part from a path. The original prop details are held in the last node in the path, while the prop part details are held in the penultimate node. The <code>getOriginalProp()</code> method can retrieve the original prop details quite easily from the path&#8217;s <code>endNode()</code> property. To get the part name (<em>shoulders</em> or <em>skirt</em>) the <code>getPath()</code> method uses the path&#8217;s <code>nodes()</code> iterator and an iterator helper function to access the last but one node.</p>

<pre><code>private class PathAccessor implements QueryResultAccessor&lt;Path&gt;{

&nbsp;&nbsp;@Override
&nbsp;&nbsp;public String getOriginalProp(Path queryResult) {
&nbsp;&nbsp;&nbsp;&nbsp;Node originalPropNode = queryResult.endNode();
&nbsp;&nbsp;&nbsp;&nbsp;return getPropertyValueOrNull(originalPropNode, &quot;prop&quot;);
&nbsp;&nbsp;}

&nbsp;&nbsp;@Override
&nbsp;&nbsp;public String getPart(Path queryResult) {
&nbsp;&nbsp;&nbsp;&nbsp;Iterable&lt;Node&gt; pathNodes = IteratorUtil.asIterable(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queryResult.nodes().iterator());
&nbsp;&nbsp;&nbsp;&nbsp;Node partNode = IteratorUtil.fromEnd(pathNodes, 1);
&nbsp;&nbsp;&nbsp;&nbsp;return getPropertyValueOrNull(partNode, &quot;part&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;private String getPropertyValueOrNull(Node node, String property){
&nbsp;&nbsp;&nbsp;&nbsp;if (!node.hasProperty(property)){
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;return node.getProperty(property).toString();
&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
}</code></pre>

<p>Having accumulated and sorted the results, our unit test can then assert that the results contain the top three most used prop parts: <strong>Dalek 1</strong>&#8216;s shoulders, <strong>Dalek 5</strong>&#8216;s skirt, and <strong>Dalek 6</strong>&#8216;s shoulders. Each of these parts appeared in 12 stories.</p>

<p>What do <strong>Dalek 1</strong>&#8216;s shoulders look like today, nearly 50 years after they first appeared on TV? Dalek 6388, of course, has the <a href="http://www.dalek6388.co.uk/where-are-the-daleks-now.htm" title="Where Are They Now?">answer</a>.</p>

<h3>Pattern Matching</h3>

<p>The Traversal Framework helped us find the hardest working Dalek prop parts in showbiz, but we still had to do quite a bit of work to accumulate the results. While the traversal description itself was relatively trivial, having to iterate nodes in each of the returned paths proved quite tedious. With the Pattern Matching library we can avoid some of the messy iterative code that cropped up in the <code>PathAccessor</code>.</p>

<p>Using the Pattern Matching library we create an abstract subgraph that describes the graph patterns we want to match in our real graph. When matching, we anchor this abstact graph to a starting node in the real graph, much as we started the traversal in the previous example from a node we&#8217;d looked up in an index. The matcher then matches subgraph instances corresponding to the nodes, relationships and constraints defined in our abstract subgraph.</p>

<pre><code>@Test
public void shouldFindTheHardestWorkingPropsUsingPatternMatchers(){
&nbsp;&nbsp;Node theDaleksNode = database.index().forNodes(&quot;species&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;.get(&quot;species&quot;, &quot;Dalek&quot;).getSingle();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;final PatternNode theDaleks = new PatternNode();&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;final PatternNode episode = new PatternNode();
&nbsp;&nbsp;final PatternNode props = new PatternNode();
&nbsp;&nbsp;final PatternNode prop = new PatternNode();
&nbsp;&nbsp;final PatternNode part = new PatternNode();
&nbsp;&nbsp;final PatternNode originalProp = new PatternNode();

&nbsp;&nbsp;theDaleks.setAssociation(theDaleksNode);
&nbsp;&nbsp;theDaleks.createRelationshipTo(episode, Rels.APPEARED_IN);
&nbsp;&nbsp;props.createRelationshipTo(episode, Rels.USED_IN);
&nbsp;&nbsp;prop.createRelationshipTo(props, Rels.MEMBER_OF);
&nbsp;&nbsp;prop.createRelationshipTo(part, Rels.COMPOSED_OF);
&nbsp;&nbsp;part.createRelationshipTo(originalProp, Rels.ORIGINAL_PROP);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;PatternMatcher pm = PatternMatcher.getMatcher();
&nbsp;&nbsp;final Iterable&lt;PatternMatch&gt; matches = pm.match(theDaleks, theDaleksNode);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;assertHardestWorkingPropParts(getSortedResults(matches, originalProp, part),
&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 1 shoulder&quot;, 12,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 5 skirt&quot;, 12,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 6 shoulder&quot;, 12); 
}</code></pre>

<p>The pattern node objects that we define as part of our abstract subgraph can then be used as keys into the match results. Below is the <code>getSortedResults()</code> method and <code>MatchAccessor</code> class for the pattern matching example. You&#8217;ll notice that we pass the <code>originalProp</code> and <code>part</code> pattern node objects into the <code>MatchAccessor</code>. The accessor then calls the match&#8217;s <code>getNodeFor()</code> method with one or other of these pattern nodes in order to retrieve the real, matched node.</p>

<pre><code>private Map&lt;String, Integer&gt; getSortedResults(Iterable&lt;PatternMatch&gt; matches, 
&nbsp;&nbsp;&nbsp;&nbsp;PatternNode originalProp, PatternNode part) {
&nbsp;&nbsp;Map&lt;String, Integer&gt; results = new ResultsAssembler&lt;PatternMatch&gt;(matches)
&nbsp;&nbsp;&nbsp;&nbsp;.getSortedResults(new MatchAccessor(originalProp, part));
&nbsp;&nbsp;return results;
}

private class MatchAccessor implements QueryResultAccessor&lt;PatternMatch&gt;{

&nbsp;&nbsp;private final PatternNode originalProp;
&nbsp;&nbsp;private final PatternNode part;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;public MatchAccessor(PatternNode originalProp, PatternNode part) {
&nbsp;&nbsp;&nbsp;&nbsp;super();
&nbsp;&nbsp;&nbsp;&nbsp;this.originalProp = originalProp;
&nbsp;&nbsp;&nbsp;&nbsp;this.part = part;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Override
&nbsp;&nbsp;public String getOriginalProp(PatternMatch queryResult) {
&nbsp;&nbsp;&nbsp;&nbsp;return queryResult.getNodeFor(originalProp).getProperty(&quot;prop&quot;).toString();
&nbsp;&nbsp;}

&nbsp;&nbsp;@Override
&nbsp;&nbsp;public String getPart(PatternMatch queryResult) {
&nbsp;&nbsp;&nbsp;&nbsp;return queryResult.getNodeFor(part).getProperty(&quot;part&quot;).toString();
&nbsp;&nbsp;}&nbsp;&nbsp;
}</code></pre>

<a name="cypher"></a><h3>Cypher</h3>

<p>The Pattern Matching example still required us to accumulate the results in order to work out which was the hardest working prop part in the original series. The abstract pattern nodes provided convenient keys into matched nodes, but we still had then to pass the matched nodes&#8217; contents to the <code>ResultsAssembler</code> in order to build a map of prop parts and usage counts. With Cypher, all that manual accumulation disappears. Better still, the entire query is expressed using a very simple, declarative syntax. Unencumbered by a &#8220;fluent&#8221; interface, a Cypher query concisely describes our desired route into the graph:</p>

<pre><code>public void shouldFindTheHardestWorkingPropsUsingCypher() throws Exception {
&nbsp;&nbsp;CypherParser parser = new CypherParser();
&nbsp;&nbsp;ExecutionEngine engine = new ExecutionEngine(universe.getDatabase());
&nbsp;&nbsp;
&nbsp;&nbsp;String cql = &quot;start daleks=(Species,species,&#039;Dalek&#039;)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;+ &quot; match (daleks)-[:APPEARED_IN]-&gt;(episode)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;+ &quot;&lt;-[:USED_IN]-(props)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;+ &quot;&lt;-[:MEMBER_OF]-(prop)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;+ &quot;-[:COMPOSED_OF]-&gt;(part)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;+ &quot;-[:ORIGINAL_PROP]-&gt;(originalprop)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;+ &quot; return originalprop.prop, part.part, count(episode.title)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;+ &quot; order by count(episode.title) desc&quot;
&nbsp;&nbsp;&nbsp;&nbsp;+ &quot; limit 3&quot;;

&nbsp;&nbsp;Query query = parser.parse(cql);
&nbsp;&nbsp; ExecutionResult result = engine.execute(query);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;assertHardestWorkingPropParts(result.javaIterator(),
&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 1&quot;, &quot;shoulder&quot;, 12,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 5&quot;, &quot;skirt&quot;, 12,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;Dalek 6&quot;, &quot;shoulder&quot;, 12);
}
&nbsp;&nbsp;
private void assertHardestWorkingPropParts(
&nbsp;&nbsp;&nbsp;&nbsp;Iterator&lt;Map&lt;String, Object&gt;&gt; results, Object... partsAndCounts) {
&nbsp;&nbsp;for (int index = 0; index &lt; partsAndCounts.length; index = index + 3){
&nbsp;&nbsp;&nbsp;&nbsp;Map&lt;String, Object&gt; row = results.next();
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(partsAndCounts[index], row.get(&quot;originalprop.prop&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(partsAndCounts[index + 1], row.get(&quot;part.part&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(partsAndCounts[index + 2], row.get(&quot;count(episode.title)&quot;));
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;assertFalse(results.hasNext());
}</code></pre>

<p>Most of that is just boilerplate code for setting up the Cypher engine and executing the query. The really concise part is the query itself. Here it is in full:</p>

<pre><code>start daleks=(Species,species,&#039;Dalek&#039;)
match (daleks)-[:APPEARED_IN]-&gt;(episode)&lt;-[:USED_IN]-(props)&lt;-[:MEMBER_OF]-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(prop)-[:COMPOSED_OF]-&gt;(part)-[:ORIGINAL_PROP]-&gt;(originalprop)
return originalprop.prop, part.part, count(episode.title)
order by count(episode.title) desc
limit 3</code></pre>

<p>Spend a couple of moments looking at it and you&#8217;ll soon appreciate its simplicity and declarative expressiveness. If only the Daleks had such power&#8230;</p>

<p>Cypher is still in its infancy, and its syntax is still in flux. In the 1.4 release timeframe, which culminates this week with the release of Neo4j 1.4 GA, Cypher performs only non-mutating operations. Over the course of the 1.5 release, we expect to add mutating operations.</p>

<h2>The Tutorial</h2>

<p>Our Neo4j tutorial is freely available from <a href="https://github.com/jimwebber/neo4j-tutorial" title="Neo4j tutorial">GitHub</a>. Download it now and try some of the exercises. And keep checking back for updates: as Neo4j grows, so will the tutorial.</p>

<p>Jim and I are also running one- and two-day versions of the tutorial at a number of conferences and other events:</p>

<ul>
<li><a href="http://uberconf.com/conference/denver/2011/07/session?id=21730" title="A Programmatic Introduction to Neo4j Workshop">UberConf 2011</a>, Denver, July 15</li>
<li><a href="http://gotocon.com/aarhus-2011/presentation/A%20Programmatic%20Introduction%20to%20Neo4j" title="A Programmatic Introduction to Neo4j Workshop">GOTO Aarhus 2011</a>, October 13</li>
<li><a href="http://gotocon.com/amsterdam-2011/presentation/Neo4j%20Tutorial" title="Neo4j Tutorial">GOTO Amsterdam 2011</a>, October 15</li>
<li><a href="http://skillsmatter.com/course/nosql/neo4j-tutorial" title="Ian Robinson and Jim Webber's Neo4j Tutorial">SkillsMatter</a>, November 3rd-4th</li>
</ul>

<p>(Dalek prop image belongs to the <a href="http://www.projectdalek.com/" title="Project Dalek">Project Dalek Forum</a> gallery, another excellent resource for Dalek prop researchers and Dalek builders.) ]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2011/07/11/the-power-of-the-daleks-and-neo4j/#comments" thr:count="5" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2011/07/11/the-power-of-the-daleks-and-neo4j/feed/atom/" thr:count="5" />
		<thr:total>5</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[From ThoughtWorks to Neo Technology]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2011/05/12/from-thoughtworks-to-neo-technology/" />
		<id>http://iansrobinson.com/?p=327</id>
		<updated>2011-05-12T16:40:04Z</updated>
		<published>2011-05-12T09:04:19Z</published>
		<category scheme="http://iansrobinson.com" term="Neo4j" />		<summary type="html"><![CDATA[Last Friday (May 6th) marked a watershed in my career, being the day I left ThoughtWorks to join Neo Technology. ThoughtWorks has been my professional home for over seven years; its technical excellence, together with its cultural and professional attitudes, are deeply imbued in my approach to software development. I leave behind many good friends, [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2011/05/12/from-thoughtworks-to-neo-technology/"><![CDATA[<p>Last Friday (May 6th) marked a watershed in my career, being the day I left ThoughtWorks to join <a href="http://neotechnology.com/" title="Neo Technology" target="_blank">Neo Technology</a>.</p>

<p><a href="http://www.thoughtworks.com/" title="ThoughtWorks" target="_blank">ThoughtWorks</a> has been my professional home for over seven years; its technical excellence, together with its cultural and professional attitudes, are deeply imbued in my approach to software development. I leave behind many good friends, a new generation of technical leaders, and a company whose focus on the entire value stream of software delivery will continue to reinvigorate and challenge the industry for a long time to come.</p>

<p>But what a company to move on to! Neo Technology is prominently stationed at the most exciting extreme of the NoSql spectrum; its graph database, <a href="http://neo4j.org/download/" title="Neo4j" target="_blank">Neo4j</a>, tackles the complexity inherent in a densely connected information universe head on. As a fit for my interests in data, its representation, and the meaning that can be extracted from pursuing the many intricate relationships between connected entities (an interest that goes all the way back to my building a hypertext system while doing postgraduate research), it can&#8217;t be bettered. On top of that, it&#8217;s a friendly, welcoming company built on innovation and deep technical excellence. I&#8217;m incredibly pleased and proud to join such an awesome team.</p>

<p>With the delightful title &#8216;Director of Customer Success&#8217; (how I&#8217;m tempted to add an exclamation mark to that&#8230;), I&#8217;m responsible for ensuring our customers get the very best value from Neo and its technologies. It&#8217;s a wide-ranging remit; one that I&#8217;ll be rounding out in more detail over the next few weeks. In the meantime I&#8217;ll be meeting some of our customers from around the world, and diving into the code to better understand the inner workings of the database. Perhaps I&#8217;ll meet some of you at the next <a href="http://skillsmatter.com/event/nosql/collaborative-neo4j" title="Neo4j User Group meetup, May 31st, London" target="_blank">Neo4j User Group meetup</a> in London on May 31st. And if you&#8217;re interested in learning more about Neo4j and/or love Doctor Who and want to explore its universe in more depth, look out for the day-long tutorials that <a href="http://jim.webber.name/" title="Jim Webber's blog" target="_blank">Jim Webber</a> and I will be running throughout the rest of this year (with the first at <a href="http://uberconf.com/conference/denver/2011/07/session?id=21730" title="Neo4j at UberConf" target="_blank">UberConf</a> in Denver, July 12-15).</p>]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2011/05/12/from-thoughtworks-to-neo-technology/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2011/05/12/from-thoughtworks-to-neo-technology/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[ThoughtWorks Technology Radar, Jan 2011, Now Available]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2011/01/31/thoughtworks-technology-radar-jan-2011-now-available/" />
		<id>http://iansrobinson.com/?p=323</id>
		<updated>2011-01-31T20:10:07Z</updated>
		<published>2011-01-31T20:10:07Z</published>
		<category scheme="http://iansrobinson.com" term="ThoughtWorks" />		<summary type="html"><![CDATA[The ThoughtWorks Technology Radar for Jan 2011 is now out. This issue we focus on: Continuous delivery Diversity of cloud offerings Using basic Web technologies in more effective and efficient ways The Radar helps decision makers understand emerging technologies and trends that affect the market today. It&#8217;s written by the ThoughtWorks Technical Advisory Board, which [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2011/01/31/thoughtworks-technology-radar-jan-2011-now-available/"><![CDATA[<p>The <a href="http://www.thoughtworks.com/radar" title="ThoughtWorks Technology Radar, Jan 2011" target="_blank">ThoughtWorks Technology Radar</a> for Jan 2011 is now out. This issue we focus on:</p>

<ul>
<li>Continuous delivery</li>
<li>Diversity of cloud offerings</li>
<li>Using basic Web technologies in more effective and efficient ways</li>
</ul>

<p>The Radar helps decision makers understand emerging technologies and trends that affect the market today. It&#8217;s written by the ThoughtWorks Technical Advisory Board, which meets regularly to discuss the global technology strategy for ThoughtWorks and the technology trends that significantly impact our industry.</p>]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2011/01/31/thoughtworks-technology-radar-jan-2011-now-available/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2011/01/31/thoughtworks-technology-radar-jan-2011-now-available/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[WS-REST 2011 Submission Deadline Extended to 10 February 2011]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2011/01/28/ws-rest-2011-submission-deadline-extended-to-10-february-2011/" />
		<id>http://iansrobinson.com/?p=318</id>
		<updated>2011-01-28T15:28:42Z</updated>
		<published>2011-01-28T15:28:42Z</published>
		<category scheme="http://iansrobinson.com" term="REST" />		<summary type="html"><![CDATA[The deadline for submitting papers for WS-REST 2011 has been extended to 10 February 2011. If you haven&#8217;t already submitted a paper, now&#8217;s your chance. Topics Applications of the REST architectural style to novel domains Design Patterns and Anti-Patterns for RESTful services RESTful service composition Inverted REST (REST for push events) Integration of Pub/Sub with [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2011/01/28/ws-rest-2011-submission-deadline-extended-to-10-february-2011/"><![CDATA[<p>The deadline for submitting papers for <a href="http://ws-rest.org/2011/">WS-REST 2011</a> has been extended to <strong>10 February 2011</strong>. If you haven&#8217;t already submitted a paper, now&#8217;s your chance.</p> 
<h2>Topics</h2>
<ul>
<li>Applications of the REST architectural style to novel domains</li>
<li>Design Patterns and Anti-Patterns for RESTful services</li>
<li>RESTful service composition</li>
<li>Inverted REST (REST for push events)</li>
<li>Integration of Pub/Sub with REST</li>

<li>Performance and QoS Evaluations of RESTful services</li>
<li>REST compliant transaction models</li>
<li>Mashups</li>
<li>Frameworks and toolkits for RESTful service implementations</li>
<li>Frameworks and toolkits for RESTful service consumption</li>
<li>Modeling RESTful services</li>
<li>Resource Design and Granularity</li>
<li>Evolution of RESTful services</li>
<li>Versioning and Extension of REST APIs</li>

<li>HTTP extensions and replacements</li>
<li>REST compliant protocols beyond HTTP</li>
<li>Multi-Protocol REST (REST architectures across protocols)</li>
</ul>

<p>Papers must be submitted electronically in PDF format. Templates are available <a href="submission">here</a></p>
<p>Easychair page: <a href="http://www.easychair.org/conferences/?conf=wsrest2011">http://www.easychair.org/conferences/?conf=wsrest2011</a></p>

<h2>Contact</h2>
<p>WS-REST Web site: <a href="http://ws-rest.org/2011/">http://ws-rest.org/2011/</a><br />

WS-REST Twitter: <a href="http://twitter.com/wsrest2011" title="http://twitter.com/wsrest2011">http://twitter.com/wsrest2011</a><br />
WS-REST Email: <a href="mailto:chairs@ws-rest.org">chairs@ws-rest.org</a>
</p>

]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2011/01/28/ws-rest-2011-submission-deadline-extended-to-10-february-2011/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2011/01/28/ws-rest-2011-submission-deadline-extended-to-10-february-2011/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[Forthcoming Events]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2011/01/23/forthcoming-events/" />
		<id>http://iansrobinson.com/?p=309</id>
		<updated>2011-01-23T19:59:57Z</updated>
		<published>2011-01-23T13:40:57Z</published>
		<category scheme="http://iansrobinson.com" term="Events" /><category scheme="http://iansrobinson.com" term="REST" />		<summary type="html"><![CDATA[I&#8217;m going to be giving variations on my RESTful domain applications talk at JFokus in Stockholm, Feb 14-16, and JAX London, April 11-13. Come along to find out all about domain application protocols: what they are, why they&#8217;re important (and implicit in almost every application, irrespective of whether we&#8217;ve given them any thought or not), [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2011/01/23/forthcoming-events/"><![CDATA[<p>I&#8217;m going to be giving variations on my RESTful domain applications talk at <a href="http://www.jfokus.se/jfokus/?lang=en&#038;" title="JFokus" target="_blank">JFokus</a>  in Stockholm, Feb 14-16, and <a href="http://jaxlondon.com/" title="JAX London" target="_blank">JAX London</a>, April 11-13. Come along to find out all about domain application protocols: what they are, why they&#8217;re important (and implicit in almost every application, irrespective of whether we&#8217;ve given them any thought or not), and how we can implement them in a RESTful application without having to import a specific process description into the client part of the app.</p>

<p>I&#8217;ll be building on some of this material at <a href="http://qconlondon.com/london-2011/" title="QCon London" target="_blank">QCon London</a> (March 9-11), but there I&#8217;ll go deeper into some implementation specifics, with examples drawn from some recent work with Microsoft&#8217;s new <a href="http://wcf.codeplex.com/" title="WCF on Codeplex" target="_blank">WCF HTTP</a> libraries. (The <a href="http://qconlondon.com/london-2011/tracks/show_track.jsp?trackOID=420" title="Building Systems With REST " target="_blank">QCon REST track</a> has a particularly stunning lineup.) Also as part of QCon London, Jim Webber and I will be running our day-long <a href="http://qconlondon.com/london-2011/presentation/REST+in+Practice+-+A+Tutorial+on+Web-based+Distributed+Systems" title="REST in Practice - A Tutorial on Web-based Distributed Systems" target="_blank">REST in Practice</a> tutorial.</p> 

<p>You can register for QCon <a href="https://secure.trifork.com/london-2011/registration/" title="QCon registration" target="_blank">here</a>. When doing so, use the <strong>ROBI100</strong> promotional code. This gives you a <strong>£100</strong> discount; at the same time, QCon will <strong>donate £100</strong> to the <a href="http://www.crisis.org.uk/index.php" title="Crisis Charity" target="_blank">Crisis Charity</a> in London (the national charity for single homeless people).</p>]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2011/01/23/forthcoming-events/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2011/01/23/forthcoming-events/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[WS-REST 2011 Call for Papers]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2011/01/07/ws-rest-2011-call-for-papers/" />
		<id>http://iansrobinson.com/?p=303</id>
		<updated>2011-01-07T09:49:30Z</updated>
		<published>2011-01-07T09:49:30Z</published>
		<category scheme="http://iansrobinson.com" term="Events" /><category scheme="http://iansrobinson.com" term="REST" />		<summary type="html"><![CDATA[The Second International Workshop on RESTful Design (WS-REST 2011) aims to provide a forum for discussion and dissemination of research on the emerging resource-oriented style of Web service design. Background Over the past few years, several discussions between advocates of the two major architectural styles for designing and implementing Web services (the RPC/ESB-oriented approach and [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2011/01/07/ws-rest-2011-call-for-papers/"><![CDATA[<p>The Second International Workshop on RESTful Design (WS-REST 2011) aims to provide a forum for discussion and dissemination of research on the emerging resource-oriented style of Web service design.</p>
<h2>Background</h2>
<p>Over the past few years, several discussions between advocates of the two major architectural styles for designing and implementing Web services (the RPC/ESB-oriented approach and the resource-oriented approach) have been mainly held outside of the research and academic community, within dedicated mailing lists, forums and practitioner communities. The RESTful approach to Web services has also received a significant amount of attention from industry as indicated by the numerous technical books being published on the topic.</p>

<p>This second edition of WS-REST, co-located with the <a href="http://wwwconference.org/www2011/">WWW2011 conference</a>, aims at providing an academic forum for discussing current emerging research topics centered around the application of REST, as well as advanced application scenarios for building large scale distributed systems.</p>
<p>In addition to presentations on novel applications of RESTful Web services technologies, the workshop program will also include discussions on the limits of the applicability of the REST architectural style, as well as recent advances in research that aim at tackling new problems that may require to extend the basic REST architectural style. The organizers are seeking novel and original, high quality paper submissions on research contributions focusing on the following topics:</p>
<ul>
<li>Applications of the REST architectural style to novel domains</li>
<li>Design Patterns and Anti-Patterns for RESTful services</li>
<li>RESTful service composition</li>
<li>Inverted REST (REST for push events)</li>
<li>Integration of Pub/Sub with REST</li>

<li>Performance and QoS Evaluations of RESTful services</li>
<li>REST compliant transaction models</li>
<li>Mashups</li>
<li>Frameworks and toolkits for RESTful service implementations</li>
<li>Frameworks and toolkits for RESTful service consumption</li>
<li>Modeling RESTful services</li>
<li>Resource Design and Granularity</li>
<li>Evolution of RESTful services</li>
<li>Versioning and Extension of REST APIs</li>

<li>HTTP extensions and replacements</li>
<li>REST compliant protocols beyond HTTP</li>
<li>Multi-Protocol REST (REST architectures across protocols)</li>
</ul>
<p>All workshop papers are peer-reviewed and accepted papers will be published as part of the ACM Digital Library. Two kinds of contributions are sought: short position papers (not to exceed 4 pages in ACM style format) describing particular challenges or experiences relevant to the scope of the workshop, and full research papers (not to exceed 8 pages in the ACM style format) describing novel solutions to relevant problems. Technology demonstrations are particularly welcome, and we encourage authors to focus on <q>lessons learned</q> rather than describing an implementation.</p>
<p>Papers must be submitted electronically in PDF format. Templates are available <a href="submission">here</a></p>
<p>Easychair page: <a href="http://www.easychair.org/conferences/?conf=wsrest2011">http://www.easychair.org/conferences/?conf=wsrest2011</a>

		</p>
<h2>Important Dates</h2>
<ul>
<li>Submission deadline: January <b>31</b>, 2011, 23.59 local time in San Francisco, CA</li>
<li>Notification of acceptance: February 15, 2011</li>
<li>Camera-ready versions of accepted papers: February 28, 2011</li>
<li>WS-REST 2011 Workshop: March 28, 2011</li>
</ul>
<h2>Program Committee Chairs</h2>

<ul>
<li>
				<a href="http://www.pautasso.info/">Cesare Pautasso</a>, Faculty of Informatics, USI Lugano, Switzerland</li>
<li>
				<a href="http://dret.net/netdret/">Erik Wilde</a>, School of Information, UC Berkeley, USA</li>
<li>
				<a href="http://dcc.puc.cl/gente/usuarios/ralarcon">Rosa Alarcon</a>, Computer Science Department, Pontificia Universidad de Chile, Chile</li>
</ul>

<h2>Program Committee</h2>
<ul>
<li>Jan Algermissen, Nord Software Consulting, Germany</li>
<li>Subbu Allamaraju, Yahoo Inc., USA</li>
<li>Mike Amudsen, USA</li>
<li>
				<a href="http://soundadvice.id.au/blog/">Benjamin Carlyle</a>, Australia</li>
<li>
				<a href="http://stucharlton.com/blog">Stuart Charlton</a>, Canada</li>

<li><a href="http://duncan-cragg.org/blog/">Duncan Cragg</a>, UK</li>
<li>
				<a href="http://bitworking.org">Joe Gregorio</a>, Google, USA</li>
<li>
				<a href="http://sw-app.org/about.html">Michael Hausenblas</a>, DERI, Ireland</li>
<li>Ralph Johnson, University of Illinois, USA</li>
<li>Rohit Khare, 4K Associates, USA</li>

<li>Yves Lafon, W3C, USA</li>
<li>
				<a href="http://www.iaas.uni-stuttgart.de/institut/mitarbeiter/leymann/indexE.php">Frank Leymann</a>, University of Stuttgart, Germany</li>
<li>
				<a href="http://iansrobinson.com/">Ian Robinson</a>, Thoughtworks, UK</li>
<li>
				<a href="http://www.innoq.com/blog/st/">Stefan Tilkov</a>, innoQ, Germany</li>

<li>
				<a href="http://steve.vinoski.net/">Steve Vinoski</a>, Verivue, USA</li>
<li><a href="http://jim.webber.name/">Jim Webber</a>, NEO4J </li>
<li>
				<a href="http://www.zurich.ibm.com/~olz/">Olaf Zimmermann</a>, IBM Zurich Research Lab, Switzerland</li>
</ul>
<h2>Contact</h2>
<p>WS-REST Web site: <a href="http://ws-rest.org/2011/">http://ws-rest.org/2011/</a><br />

WS-REST Twitter: <a href="http://twitter.com/wsrest2011" title="http://twitter.com/wsrest2011">http://twitter.com/wsrest2011</a><br />
WS-REST Email: <a href="mailto:chairs@ws-rest.org">chairs@ws-rest.org</a>
		</p>

]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2011/01/07/ws-rest-2011-call-for-papers/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2011/01/07/ws-rest-2011-call-for-papers/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[RESTful Domain Application Protocols]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2010/10/15/restful-domain-application-protocols/" />
		<id>http://iansrobinson.com/?p=281</id>
		<updated>2010-10-15T15:46:42Z</updated>
		<published>2010-10-15T15:46:42Z</published>
		<category scheme="http://iansrobinson.com" term="Events" /><category scheme="http://iansrobinson.com" term="REST" /><category scheme="http://iansrobinson.com" term="REST in Practice" />		<summary type="html"><![CDATA[Last week I gave a TechTalk on RESTful domain application protocols at the Microsoft Development Center in Copenhagen. The video for the talk is now online at Channel 9. My thanks to Microsoft for their invite and hospitality, and to the audience members for their attention and questions. If you want to learn more about [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2010/10/15/restful-domain-application-protocols/"><![CDATA[<p>Last week I gave a TechTalk on RESTful domain application protocols at the Microsoft Development Center in Copenhagen. The video for the talk is now online at <a href="http://channel9.msdn.com/posts/TechTalk-RESTful-Application-Protocols-From-Design-to-Implementation" title="RESTful Application Protocols, From Design to Implementation" target="_blank">Channel 9</a>.</p>

<p>My thanks to Microsoft for their invite and hospitality, and to the audience members for their attention and questions.</p>

<p>If you want to learn more about domain application protocols, hypermedia, event-driven systems with Atom, and security on the wild web &#8211; and you&#8217;re in London next week &#8211; why not sign up for a day-long REST tutorial being run by me and <a href="http://jim.webber.name" title="Jim Webber's blog" target="_blank">Jim Webber</a>? We&#8217;re at <a href="http://www.software-architect.co.uk/sessions/postworkshops.asp">Software Architect 2010</a> on Friday, 22nd October: you can register for the conference and tutorial <a title="Register for Software Architect 2010" target="_blank" href="http://www.software-architect.co.uk/registration/">here</a>.</p>]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2010/10/15/restful-domain-application-protocols/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2010/10/15/restful-domain-application-protocols/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[REST in Practice has arrived]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2010/09/22/rest-in-practice-has-arrived/" />
		<id>http://iansrobinson.com/?p=257</id>
		<updated>2010-09-22T14:54:45Z</updated>
		<published>2010-09-22T14:54:45Z</published>
		<category scheme="http://iansrobinson.com" term="REST" /><category scheme="http://iansrobinson.com" term="REST in Practice" />		<summary type="html"><![CDATA[Today I received a lovely present from O&#8217;Reilly: a copy of REST in Practice, new off the press. A big, big thanks to Jim and Savas, who asked me to write with them shortly after they&#8217;d started out on the book; I&#8217;m enormously proud of what we&#8217;ve achieved together. Thanks too to all our reviewers, [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2010/09/22/rest-in-practice-has-arrived/"><![CDATA[<p>Today I received a lovely present from O&#8217;Reilly: a copy of <a href="http://restinpractice.com" title="REST in Practice" target="_blank"><em>REST in Practice</em></a>, new off the press.</p>
<p>A big, big thanks to <a href="http://jim.webber.name/" title="Jim Webber's blog" target="_blank">Jim</a> and <a href="http://savas.me/" title="Savas Parastatidis' blog" target="_blank">Savas</a>, who asked me to write with them shortly after they&#8217;d started out on the book; I&#8217;m enormously proud of what we&#8217;ve achieved together. Thanks too to all our reviewers, and to the wonderful people at O&#8217;Reilly who&#8217;ve guided us through the production process and made of our words a fine book &#8211; names on the book&#8217;s <a href="http://restinpractice.com/acknowledgements.html" title="REST in Practice acknowledgements" target="_blank">site</a>. And finally, a heartfelt thanks to Lottie, Tiger and Elliot, who didn&#8217;t need a book to tell them how to use links, but who let me write one anyway.</p>

<p>The book is available for pre-order on Amazon (<a href="http://www.amazon.co.uk/REST-Practice-Hypermedia-Systems-Architecture/dp/0596805829/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1271772697&#038;sr=1-1" title="REST in Practice on Amazon UK" target="_blank">UK</a> and <a href="http://www.amazon.com/gp/product/0596805829/ref=s9_simh_gw_p14_i1?pf_rd_m=ATVPDKIKX0DER&#038;pf_rd_s=center-2&#038;pf_rd_r=1FJEX5ASH5KQ29FTW4J1&#038;pf_rd_t=101&#038;pf_rd_p=470938631&#038;pf_rd_i=507846" title="REST in Practice on Amazon US" target="_blank">US</a>), but if you want the chance to win a free copy, <a href="http://savas.me/blog/1087" title="How to get a free copy of 'REST in Practice'" target="_blank">Savas</a> has all the details.</p>]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2010/09/22/rest-in-practice-has-arrived/#comments" thr:count="2" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2010/09/22/rest-in-practice-has-arrived/feed/atom/" thr:count="2" />
		<thr:total>2</thr:total>
	</entry>
		<entry>
		<author>
			<name>iansrobinson</name>
						<uri>http://www.iansrobinson.com</uri>
					</author>
		<title type="html"><![CDATA[REST in Practice Tutorial, London, Oct 22nd]]></title>
		<link rel="alternate" type="text/html" href="http://iansrobinson.com/2010/09/21/rest-in-practice-tutorial-london-oct-22nd/" />
		<id>http://iansrobinson.com/?p=269</id>
		<updated>2010-09-21T09:58:48Z</updated>
		<published>2010-09-21T09:58:48Z</published>
		<category scheme="http://iansrobinson.com" term="Events" /><category scheme="http://iansrobinson.com" term="REST" /><category scheme="http://iansrobinson.com" term="REST in Practice" />		<summary type="html"><![CDATA[Jim Webber and I will be running a day-long REST tutorial at Software Architect 2010, in London on Friday, 22nd October. You can register for the conference and tutorial here. Early bird discounts apply throughout the remainder of this week. The tutorial agenda closely follows the structure of REST in Practice, which hits the shelves [...]]]></summary>
		<content type="html" xml:base="http://iansrobinson.com/2010/09/21/rest-in-practice-tutorial-london-oct-22nd/"><![CDATA[<p><a href="http://jim.webber.name" title="Jim Webber's blog" target="_blank">Jim Webber</a> and I will be running a day-long REST tutorial at <a href="http://www.software-architect.co.uk/sessions/postworkshops.asp">Software Architect 2010</a>, in London on Friday, 22nd October. You can register for the conference and tutorial <a title="Register for Software Architect 2010" target="_blank" href="http://www.software-architect.co.uk/registration/">here</a>.</p>
<p>Early bird discounts apply throughout the remainder of this week.</p>

<p>The tutorial agenda closely follows the structure of <a title="REST in Practice" target="_blank" href="http://restinpractice.com"><em>REST in Practice</em></a>, which hits the shelves later this week:</p>
<ul>
<li>Introduction and Motivation</li>
<li>The Web Architecture</li>
<li>Simple Web Integration including POX and URI tunnelling</li>
<li>CRUD Services using URI templates and HTTP</li>
<li>Semantics using Microformats and RDF</li>
<li>Hypermedia and the REST architectural style</li>
<li>Scalability and how a text-based client-server polling protocol outperforms everything else!</li>
<li>ATOM and ATOMPub for event-driven and pub/sub applications</li>
<li>Security</li>
<li>Conclusions and further thoughts</li>
</ul>]]></content>
		<link rel="replies" type="text/html" href="http://iansrobinson.com/2010/09/21/rest-in-practice-tutorial-london-oct-22nd/#comments" thr:count="1" />
		<link rel="replies" type="application/atom+xml" href="http://iansrobinson.com/2010/09/21/rest-in-practice-tutorial-london-oct-22nd/feed/atom/" thr:count="1" />
		<thr:total>1</thr:total>
	</entry>
	</feed>
