<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>David Cassel</title>
	
	<link>http://blog.davidcassel.net</link>
	<description>on Software Development and Entrepreneurism</description>
	<lastBuildDate>Wed, 01 Sep 2010 03:31:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/DavidCassel" /><feedburner:info uri="davidcassel" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><item>
		<title>XPath: using the root element</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/gtg5VvZ2zIg/</link>
		<comments>http://blog.davidcassel.net/2010/08/xpath-using-the-root-element/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 03:31:17 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[xpath]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=178</guid>
		<description><![CDATA[In XQuery, I commonly find myself writing XPath statements to navigate into some block of XML to find some tasty nugget that&#8217;s in there somewhere. When doing so, I&#8217;ve found one particular aspect that frequently throws me off, getting me empty results instead of the information I wanted. Having finally figured it out, and after [...]]]></description>
			<content:encoded><![CDATA[<p>In XQuery, I commonly find myself writing XPath statements to navigate into some block of XML to find some tasty nugget that&#8217;s in there somewhere. When doing so, I&#8217;ve found one particular aspect that frequently throws me off, getting me empty results instead of the information I wanted. Having finally figured it out, and after confirming with a friend that I&#8217;m not the only one who messes this up, here&#8217;s a little lesson to help you write your XPath.</p>
<p>Let&#8217;s start with the question that I found confusing: if you want to specify a full XPath from the top node down to what you&#8217;re looking for, should you specify the root node? Seems like a simple thing, but as is so often the case, the answer is, &#8220;it depends&#8221;. Consider this XML:</p>
<pre>&lt;doc&gt;
  &lt;book&gt;
    &lt;name&gt;The Fellowship of the Ring&lt;/name&gt;
  &lt;/book&gt;
  &lt;author&gt;
    &lt;name&gt;J. R. R. Tolkien&lt;/name&gt;
  &lt;/author&gt;
&lt;/doc&gt;</pre>
<p>I want to retrieve the name of the book using XPath. I can&#8217;t just ask for &#8220;//name&#8221;, because I&#8217;d get two results, the book&#8217;s name and the author&#8217;s. I&#8217;ll be more precise and specify the full path. So what XPath do I use: &#8220;/doc/book/name&#8221; or &#8220;/book/name&#8221;?</p>
<p>It depends on how we got this chunk of XML. If our XML is a document, then the variable that holds the XML is pointing to the whole document, and &lt;doc/&gt; is the top-level node of that doc. So, assuming that /book.xml contains the XML above:</p>
<pre>let $doc := fn:doc('/book.xml')
return $doc/doc/book/name</pre>
<p>But if the XML is constructed, then the node that holds it is pointing to the top-level node itself &#8212; there is no document.</p>
<pre>let $str :=
  &lt;doc&gt;
    &lt;book&gt;
      &lt;name&gt;The Fellowship of the Ring&lt;/name&gt;
    &lt;/book&gt;
    &lt;author&gt;
      &lt;name&gt;J. R. R. Tolkien&lt;/name&gt;
    &lt;/author&gt;
  &lt;/doc&gt;
return $str/book/name</pre>
<p>Simple as that. Now a little test: which XPath expression would you use in this case?</p>
<pre>let $str :=
  xdmp:unquote('
    &lt;doc&gt;
      &lt;book&gt;
        &lt;name&gt;The Fellowship of the Ring&lt;/name&gt;
      &lt;/book&gt;
      &lt;author&gt;
        &lt;name&gt;J. R. R. Tolkien&lt;/name&gt;
      &lt;/author&gt;
    &lt;/doc&gt;')</pre>
<p>To find the answer, you need to know that xdmp:unquote() returns a document-node() (actually one or more). Now that we know we&#8217;ll get a document back, the answer is simple:</p>
<pre>return $doc/doc/book/name</pre>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/gtg5VvZ2zIg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/08/xpath-using-the-root-element/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/08/xpath-using-the-root-element/</feedburner:origLink></item>
		<item>
		<title>Losing my senses</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/d9k3eWi_A3w/</link>
		<comments>http://blog.davidcassel.net/2010/08/losing-my-senses/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 02:49:15 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/2010/08/losing-my-senses/</guid>
		<description><![CDATA[Today for a while I was without Internet access and I had this sensation I&#8217;ve noticed before, and mentioned to a few people: I&#8217;ve gotten to the point where being cut off from the Internet is like losing one of my senses. Not always&#8230; if I&#8217;m on a mountain trail somewhere, I&#8217;m not worried about [...]]]></description>
			<content:encoded><![CDATA[<p>Today for a while I was without Internet access and I had this sensation I&#8217;ve noticed before, and mentioned to a few people: I&#8217;ve gotten to the point where being cut off from the Internet is like losing one of my senses. Not always&#8230; if I&#8217;m on a mountain trail somewhere, I&#8217;m not worried about checking my gmail. But if I&#8217;m trying to do something in my everyday life, and I have to do it without my iPhone or laptop or something, I feel a little handicapped. </p>
<p>This may be a sign of addiction. :) </p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/d9k3eWi_A3w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/08/losing-my-senses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/08/losing-my-senses/</feedburner:origLink></item>
		<item>
		<title>Gotcha – sequence index evaluation</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/u33sbooTfvY/</link>
		<comments>http://blog.davidcassel.net/2010/07/gotcha-sequence-index-evaluation/#comments</comments>
		<pubDate>Wed, 14 Jul 2010 02:03:52 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[gotcha]]></category>
		<category><![CDATA[marklogic]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=171</guid>
		<description><![CDATA[Every now and then I get caught by this little gotcha, so I figured I&#8217;d share and hopefully by writing about it, I&#8217;ll remember to do this right. Let&#8217;s start with a little something simple, shall we?
let $seq := (1 to 100)
return $seq[10]
Simple, as promised. I create a sequence of numbers from one to one [...]]]></description>
			<content:encoded><![CDATA[<p>Every now and then I get caught by this little gotcha, so I figured I&#8217;d share and hopefully by writing about it, I&#8217;ll remember to do this right. Let&#8217;s start with a little something simple, shall we?</p>
<pre>let $seq := (1 to 100)
return $seq[10]</pre>
<p>Simple, as promised. I create a sequence of numbers from one to one hundred and I ask for the tenth one. I run this and I get 10 as a result. So far, so good.</p>
<p>Now, suppose that I want to get a random element of this sequence. MarkLogic Server provides an xdmp:random() function, so this should be easy, too:</p>
<pre>let $seq := (1 to 100)
return $seq[xdmp:random(99) + 1]</pre>
<p>Randomly generate a number from 0 to 99, add one to get us into the 1 to 100 range, and return the value with that index. I run this one and I get&#8230; the empty sequence. I run it again and I get two values. I run it again and get one. What&#8217;s going on?</p>
<p>To see what&#8217;s going on, let&#8217;s run this in CQ using the Profile button.</p>
<table>
<tbody>
<tr>
<td>expression</td>
<td>count</td>
</tr>
<tr>
<td>let $seq := 1 to 100 return $seq[xdmp:random(9) + 1]</td>
<td>1</td>
</tr>
<tr>
<td>xdmp:random(9) + 1</td>
<td>100</td>
</tr>
<tr>
<td>xdmp:random(9)</td>
<td>100</td>
</tr>
<tr>
<td>$seq[xdmp:random(9) + 1]</td>
<td>1</td>
</tr>
<tr>
<td>1 to 100</td>
<td>1</td>
</tr>
</tbody>
</table>
<p>What we see is the xdmp:random() expression getting called 100 times. Yet if you run Profile on the first implementation ($seq[10]), you&#8217;ll see that $seq[10] is evaluated just once and that &#8220;10&#8243; doesn&#8217;t show up as an expression.</p>
<p>When I put a constant in the index operator ([]), XQuery knows exactly which element(s) I want &#8212; no work is required. But when I put an expression there, it evaluates the expression once for each element in the sequence and checks whether the current index matches the expression. That lets us do complicated things like</p>
<div id="_mcePaste">let $seq := (1 to 100)</div>
<div id="_mcePaste">return $seq[if (math:fmod(fn:position(), 3) = 0) then fn:position() else ()]</div>
<p>(return the elements whose indexes are divisible by three) but it comes at the cost of evaluating that expression more often than you might expect.</p>
<p>So what should we do instead? Happily, there is a simple solution:</p>
<pre>let $seq := (1 to 100)
let $index := xdmp:random(99) + 1
return $seq[$index]</pre>
<p>This approach returns one value every time it&#8217;s called, and profile shows us that each expression is evaluated only once.</p>
<p>Moral of the story: if you have an expression as a sequence index, make sure it&#8217;s not doing more work than you intend. Profiling, as always, is your friend.</p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/u33sbooTfvY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/07/gotcha-sequence-index-evaluation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/07/gotcha-sequence-index-evaluation/</feedburner:origLink></item>
		<item>
		<title>Calling a function on all permutations of a sequence</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/YZiVjyj-zLU/</link>
		<comments>http://blog.davidcassel.net/2010/05/calling-a-function-on-all-permutations-of-a-sequence/#comments</comments>
		<pubDate>Thu, 20 May 2010 15:54:01 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[xquery]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=159</guid>
		<description><![CDATA[A project I&#8217;m working on required me to call a function on each permutation of a sequence. I said to myself, &#8220;Surely, you can&#8217;t be the only person needing to do that in XQuery&#8221;. Having heard that from such a reliable source, I figured I should share.
(: Print an index and the selected members of [...]]]></description>
			<content:encoded><![CDATA[<p>A project I&#8217;m working on required me to call a function on each permutation of a sequence. I said to myself, &#8220;Surely, you can&#8217;t be the only person needing to do that in XQuery&#8221;. Having heard that from such a reliable source, I figured I should share.</p>
<pre>(: Print an index and the selected members of the sequence. :)
declare function local:print($index, $values, $selections, $connector) {
    fn:concat($index, ": ", fn:string-join($values[$selections], $connector))
};

(: Apply the specified function to each permutation of $seq. $data is
 : provided as a pass-through.
 :)
declare function local:apply-on-permutations($seq as item()*,
            $function as xdmp:function, $data)
{
    let $len := fn:count($seq)
    for $i in (1 to xs:int(math:pow(2, $len) - 1))
    let $targets :=
        for $bit in (1 to $len)
        let $shifted :=
            if ($bit &gt; 1) then
                xs:int($i div (math:pow(2, $bit - 1)))
            else $i
        return
            if (math:fmod($shifted, 2) eq 1) then
                $bit
            else ()
    return
        xdmp:apply($function, $i, $seq, $targets, $data)
};

let $seq := ('a', 'b', 'c', 'd')
return local:apply-on-permutations($seq, xdmp:function(xs:QName("local:print")), ',')</pre>
<p>Calling this function generates this output:</p>
<pre>1: a
2: b
3: a,b
4: c
5: a,c
6: b,c
7: a,b,c
8: d
9: a,d
10: b,d
11: a,b,d
12: c,d
13: a,c,d
14: b,c,d
15: a,b,c,d</pre>
<p>I&#8217;m sure you&#8217;ll sleep better tonight knowing that this is available to you.</p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/YZiVjyj-zLU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/05/calling-a-function-on-all-permutations-of-a-sequence/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/05/calling-a-function-on-all-permutations-of-a-sequence/</feedburner:origLink></item>
		<item>
		<title>Do it yourself</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/u7uadOIa1hg/</link>
		<comments>http://blog.davidcassel.net/2010/05/do-it-yourself/#comments</comments>
		<pubDate>Tue, 04 May 2010 05:44:47 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Entrepreneurism]]></category>
		<category><![CDATA[lessons]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=157</guid>
		<description><![CDATA[I have a little story to tell that I hope will inspire someone to pursue an entrepreneurial goal.
I came across a notebook recently. I don&#8217;t remember exactly when I used this one, but it was somewhere around &#8216;97 or &#8216;98. Back then, I was playing chess on a web site called ItsYourTurn.com. I loved the [...]]]></description>
			<content:encoded><![CDATA[<p>I have a little story to tell that I hope will inspire someone to pursue an entrepreneurial goal.</p>
<p>I came across a notebook recently. I don&#8217;t remember exactly when I used this one, but it was somewhere around &#8216;97 or &#8216;98. Back then, I was playing chess on a web site called ItsYourTurn.com. I loved the concept. You make a move, and your opponent gets an email saying, &#8220;It&#8217;s your turn. Click this link to go to your game.&#8221; The length of the clock varied, but you could set up casual games where you had 30 days to make a move. Tournaments were 28 or 48 hours. It was the first time I saw a web-based approach to correspondence chess, and I was hooked. That was a pace I could keep up with.</p>
<p>So the concept was great, I was getting to play lots of chess, and I was even playing in tournaments. Great! But the site lacked some features I wanted. I wanted to be able to move the pieces around to explore what I might do. I wanted to send conditional moves. The details don&#8217;t matter, the point is, the site was 80% of what I wanted, but the other 20% annoyed me.</p>
<p>Back to the notebook. I started jotting notes about building a web site to compete with ItsYourTurn. Among other things, I figured out how much it would cost me to get my competing site off the ground. Not so much in developer time, but out-of-pocket costs to register a domain name and get the site hosted. My notebook says that the cheap monthly hosting I was looking at was about $30 a month. These days, you can get started for less than $5 per month, at least in your prototype stage.</p>
<p>I ended up deciding not to build the competing site. Why not? The calculus was pretty simple: 1) the financial and time costs felt pretty big (at the time), and more importantly, 2) they were doing 80% of what I wanted &#8212; surely by the time I could offer the basics, they&#8217;d get the other 20% done and I would have wasted my time.</p>
<p>Fast forward to 2009. 10+ years later, they still didn&#8217;t have the features I wanted. Not that they had been idle: they&#8217;d added lots of other games and variants of those games. They worked hard to expand in a direction that I didn&#8217;t care about. (Obviously others did.) I ended up finding another site that did provide what I wanted, and that&#8217;s where I play now.</p>
<p>The moral of the story is this: if you&#8217;re unhappy with a site you&#8217;re using, and there isn&#8217;t somebody else doing it the right way, don&#8217;t assume they&#8217;re going to fix it. Your view of what&#8217;s better might be different from theirs. But if you want it, you&#8217;re probably not the only one. You&#8217;re a developer (or you probably wouldn&#8217;t be reading this blog) &#8212; don&#8217;t wait for something better to magically appear. Odds are somebody&#8217;s going to do it, and they&#8217;ll make some money in the process. Why not step up and make that somebody you?</p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/u7uadOIa1hg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/05/do-it-yourself/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/05/do-it-yourself/</feedburner:origLink></item>
		<item>
		<title>A RESTful chess service: part 5</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/jGDTZ7j9_N0/</link>
		<comments>http://blog.davidcassel.net/2010/05/a-restful-chess-service-part-5/#comments</comments>
		<pubDate>Mon, 03 May 2010 15:09:46 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[chess]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=134</guid>
		<description><![CDATA[Welcome to part 5 of my series on designing a RESTful chess service. Don&#8217;t worry &#8212; today&#8217;s is the last of the planning posts, then we get to some code.
The last two steps laid out by the authors of RESTful Web Services are to consider the typical course of events and to consider error conditions. Let&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<div id="_mcePaste">Welcome to part 5 of my series on designing a RESTful chess service. Don&#8217;t worry &#8212; today&#8217;s is the last of the planning posts, then we get to some code.</div>
<div>The last two steps laid out by the authors of <span style="font-family: 'Lucida Grande', Verdana, Arial, sans-serif; line-height: 16px; color: #111111;"><a style="color: #114477; text-decoration: underline;" href="http://www.amazon.com/gp/product/0596529260?ie=UTF8&amp;tag=shastuonl-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596529260" target="_blank">RESTful Web Services</a> are to consider the typical course of events and to consider error conditions. Let&#8217;s get started. </span></div>
<h2>The Typical Course of Events</h2>
<p>There are two main use cases for this service. The first is a Tournament Director reporting the results of games. In this case, the TD will POST a PGN game to /games. The typical course here is that the service will translate the PGN to XML, use some of the fields to construct a URL, store the game, and returns its new URL. For this first version of the service, uploading a game is the only way to add data to the database. The other main use case is someone using the service to browse the contents of the database. Here, we expect that the consumer of the service will use a proper URL and the service will return a list of games that match. In the previous post, I worked out that the search results will be paginated.</p>
<p>As a secondary use case, the service allows a TD to upload a correction to a PGN record. This case leads to some interesting results. Naturally, if someone uses the service to retrieve an updated game, we want to show the updated version. The interesting part is what happens to the URL. Since we are constructing the game URLs from the PGN headers, updating a game record may well change the game&#8217;s URL. For instance, suppose that a TD POSTS a game with these PGN headers:</p>
<pre>[Event "February 2010 Octet X"]
[Site "http://redhotpawn.com"]
[Date "2010.02.17"]
[Round "1"]
[White "David Cassel"]
[Black "sagator"]
[Result "1/2-1/2"]</pre>
<p>The game will be accessible through the URL &#8220;/games/February+2010+Octet+X/http%3A%2F%2Fredhotpawn.com /2010.02.17/1/David+Cassel/sagator&#8221;. Later, the TD realizes that this site is usually recorded with the full address, including the &#8220;www&#8221;. The service will allow the TD to PUT the PGN with the corrected header ([Site "http://www.redhotpawn.com"]) to the URL created by the earlier POST. Two things happen as a result. First, the game will now be available at a URL based on the corrected headers: &#8220;/games/February+2010+Octet+X/%3A%2F%2Fredhotpawn.com/ 2010.02.17/1/David+Cassel/sagator&#8221;. But we also need to think about what to do if someone requests the original URL. After all, someone may have conducted a search or bookmarked the URL and may try to retrieve the game. HTTP code 301 Moved Permanently is the way to go here.</p>
<p>These seems like a good time to point out one of the simplifying assumptions I&#8217;ve made: that there&#8217;s no need to log in. In a real system, I would limit who is allowed to POST or PUT data, and might limit search and retrieval, depending on the intended use of the service. That means I&#8217;d need to think through how to handle security, how to model my users, how to respond to unauthorized access attempts, and so forth. MarkLogic Server provides handy ways to handle all that, but it&#8217;s not what I want to focus on right now. Maybe I&#8217;ll add that to the service in a future post.</p>
<h2>Consider What Can Go Wrong</h2>
<p>The steps listed by the book&#8217;s authors includes trying to anticipate what might go wrong while the service is being used. A little defensive programming can go a long way. So&#8230; what could possibly go wrong?</p>
<p>Let&#8217;s start with an obvious case: someone requesting a URL that doesn&#8217;t correspond to anything in the database. Is it worthwhile to list something basic like this? Personally, I think so. Listing such cases makes you decide whether you should return 404 Not Found, or simply an empty list with a 200 Success (you probably wouldn&#8217;t want this, but I&#8217;ve seen it happen). If someone asks the service for a game that isn&#8217;t in the database, the service will return a 404, but a search that has no results will get a 200 with an empty &lt;results/&gt; node. It also helps you to remember to address those cases in the code, so you don&#8217;t accidentally end up throwing a 500 Server Error.</p>
<p>Another potential error is a conflict &#8212; a TD POSTing a game with PGN fields that match those of a game already in the database. If this happens, we&#8217;ll return 409 Conflict, along with the URL of the conflicting game. That way, the TD will be able to look at the game that&#8217;s already in the database. It might be that the TD accidentally POSTed the same game twice, or it may be a mistake in one of the fields. By providing useful information, the consumer of the service will be able to figure out what went wrong.</p>
<p>Any time you expect a certain format for the data your users send you, you need to be prepared for the data not to match the format. In the chess service case, the PGN might be invalid, or it might be valid PGN that is missing some fields we require. We&#8217;ll treat these cases the same way, responding with a 400 Bad Request and a message stating the requirement of valid PGN and a list of required fields.</p>
<p>One way that I like to think of how things go wrong is to glance over <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" target="_blank">the list of HTTP response codes</a>. Sometimes it helps me think of a case that I might have overlooked otherwise. Based on a look at the list, I remembered that there are only a small number of permitted methods (GET on a particular game, event, player, or search; POST on /games; PUT on a particular game). Outside of those, we&#8217;ll return 405 Method Not Allowed.</p>
<p>I think that about covers it. I&#8217;ve now worked through the design for my RESTful chess service, informed in a couple places by some exploratory coding. Next time, we&#8217;ll look at how to implement the service with MarkLogic Server.</p>
<p>I found the procedure listed out by Richardson &amp; Ruby to be a helpful one. Even though I&#8217;ve made some simplifying assumptions for this exercise, having a set of steps helped me go about the design in an organized way.</p>
<p>Do you have a particular approach you use to design a service?</p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/jGDTZ7j9_N0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/05/a-restful-chess-service-part-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/05/a-restful-chess-service-part-5/</feedburner:origLink></item>
		<item>
		<title>A RESTful chess service: part 4</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/OLIeNpYpFxM/</link>
		<comments>http://blog.davidcassel.net/2010/04/a-restful-chess-service-part-4/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 14:05:11 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[chess]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=139</guid>
		<description><![CDATA[This is part four in a series of posts walking through the process of building a RESTful chess service. I&#8217;ve been slacking off a bit in the pace of my posts, but hopefully that will pick back up &#8212; I have a bit more travel coming up, and evenings spent hanging out in hotel rooms [...]]]></description>
			<content:encoded><![CDATA[<p>This is part four in a series of posts walking through the process of building a RESTful chess service. I&#8217;ve been slacking off a bit in the pace of my posts, but hopefully that will pick back up &#8212; I have a bit more travel coming up, and evenings spent hanging out in hotel rooms are good for getting posts written!</p>
<p>The <a href="http://blog.davidcassel.net/2010/03/a-restful-chess-service-part-3/" target="_self">previous post</a> in this series laid out representations of individual games. As part of that, I picked URLs for events and players, rooted at /events/ and /players/.</p>
<p>I think I&#8217;ve mentioned that I intend this blog as learning-in-public sort of exercise. Here&#8217;s a case in point: I don&#8217;t like the way I set up the event URLs in my last post. I have pictured that the representation of an event would list the participating players and the games. However, I set up the URL to only mention the name of the event. The problem with that is that the name of an event (&#8220;First Saturday Quads&#8221;) does not uniquely identify a specific tournament. To do that, you need to add at least the site and the date(s) on which the tournament was played. As such, I&#8217;m now revising the URL of event to take the form: /events/&lt;event name&gt;/&lt;site name&gt;/&lt;date range&gt;. I&#8217;m allowing (but not requiring) a date range, because while some events are over in one day, some last for a few days, weeks, or even (in the case of <a href="http://en.wikipedia.org/wiki/Correspondence_chess" target="_blank">postal chess</a>) years.</p>
<h2>Representing Events and Players</h2>
<p>Under the use cases I&#8217;ve identified so far, there is no way to enter event data other than the game information that shows up in the PGN. An event, under my setup so far, is simply a collection of games. I&#8217;m going to run with that for now, but I can picture storing addition infomation such as the name of the Tournament Director and the tournament winner. Eventually, that would require accepting a new representation for a tournament.</p>
<p>Since we don&#8217;t have much data about events, the representation won&#8217;t be that complex. Here&#8217;s the representation for /events/February 2010 Octet X/http%3A%2F%2Fwww.redhotpawn.com/2010.02.17-2010.04.01:</p>
<pre>&lt;event&gt;
  &lt;name&gt;February 2010 Octet X&lt;/name&gt;
  &lt;site&gt;http://www.redhotpawn.com&lt;/site&gt;
  &lt;date-start&gt;2010-02-17&lt;/date-start&gt;
  &lt;date-end&gt;2010-04-01&lt;/date-end&gt;
  &lt;players&gt;8&lt;/players&gt;
&lt;/event&gt;</pre>
<p>Likewise, what we know about players comes from the PGN information about individual games. For our player representation, we&#8217;ll give the name and what we know about the player &#8212; not much at this point.</p>
<pre>&lt;player&gt;
  &lt;name&gt;Cassel, David&lt;/name&gt;
  &lt;counts events="2" games="100"/&gt;
  &lt;rating type="highest"&gt;1546&lt;/rating&gt;
  &lt;rating type="latest"&gt;1542&lt;/rating&gt;
&lt;/player&gt;</pre>
<p>One more thing before we move on. I mentioned earlier that if we wanted to add, say, the Tournament Director to the representation of an event, we&#8217;d have to allow a consumer of this service to PUT a new representation. But notice that what&#8217;s contained in the representations right now is extracted from the actual game data. What would we do if someone uploaded a representation that contradicted what we knew from the game data? That&#8217;s an application-specific decision; we could either decide to overwrite what we saw in the game PGN data, or we could decide it is involatile. If we go with the latter approach, we could disregard contradicting information or trigger an error. Since I&#8217;m not going to allow PUTs to Event and Player resources, I don&#8217;t have to worry about it &#8212; but when you&#8217;re designing your service, watch out for gotchas like that and think through what should happen. (That&#8217;s step 9 in <a href="http://www.amazon.com/gp/product/0596529260?ie=UTF8&amp;tag=shastuonl-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596529260" target="_blank">our authors&#8217; procedure</a>, for those keeping track.)</p>
<h2>Representing Search</h2>
<p>I&#8217;m going to offer two ways to search. The first will look pretty normal. I&#8217;ll use a URL like this: /search?q=. Is this RESTful? How does &#8220;search&#8221; count as a resource? Simply enough: search is an algorithm; the <em>results</em> of that algorithm are a resource, complete with a representation.</p>
<p>This is a free text search. Results may include games, players and events.</p>
<pre>/search?q=quads
&lt;results&gt;
  &lt;game&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/2000.04.01/1/Joe+Abner/David+Cassel&lt;/game&gt;
  &lt;game&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/2003.02.01/1/Joe+Demetrick/David+Cassel&lt;/game&gt;
  &lt;game&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/2000.04.01/1/David+Cassel/Charles+Jay&lt;/game&gt;
  &lt;game&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/2000.04.01/1/David+Cassel/Fred+Austin&lt;/game&gt;
  &lt;event&gt;/events/First+Saturday+Quads/West+Chester+Chess+Club/2000.04.01&lt;/event&gt;
&lt;/results&gt;</pre>
<p>We can see now how the decision to use transparent URLs is helpful: we can present these results a user, who will be able to determine something about them without having to load up the contents of the individual documents. But wait, there&#8217;s more! Let&#8217;s also set up search by path variable: we&#8217;ll let the user specify the parts they know about and use &#8220;any&#8221; for the remainder. We&#8217;ll only apply this style to game searches for now. I&#8217;ll also disallow wildcards, but you can probably see how that would be a useful extension. Let&#8217;s look at an example:</p>
<pre>/games/First+Saturday+Quads/West+Chester+Chess+Club/any/David+Cassel/any</pre>
<p>This URL will return a list of all games in which I played white in the West Chester Chess Club&#8217;s First Saturday Quads event, regardless or date or opponent. Of course, in a large database this could yield a lot of results, especially if you used &#8220;any&#8221; for a lot of fields. So let&#8217;s add two more fields in order to allow for paging: page number and page size.</p>
<pre>/games/First+Saturday+Quads/West+Chester+Chess+Club/any/David+Cassel/any/1/10</pre>
<pre>&lt;results&gt;
  &lt;game&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/2000.04.01/1/Joe+Abner/David+Cassel&lt;/game&gt;
  &lt;game&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/2003.02.01/1/Joe+Demetrick/David+Cassel&lt;/game&gt;
  &lt;game&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/2000.04.01/1/David+Cassel/Charles+Jay&lt;/game&gt;
  &lt;game&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/2000.04.01/1/David+Cassel/Fred+Austin&lt;/game&gt;
  &lt;!-- six more &lt;game/&gt; results, then: --&gt;
  &lt;page&gt;1&lt;/page&gt;
  &lt;link rel="next"&gt;/games/First+Saturday+Quads/West+Chester+Chess+Club/any/David+Cassel/any/2/10&lt;/link&gt;
&lt;/results&gt;</pre>
<p>Now we&#8217;re asking for the same set of results as before, but we want the first page of 10 results. The &lt;page/&gt; element toward the bottom identifies the page and the &lt;link/&gt; element shows how to get to the next page. After the first page, the service would also provide a &lt;link rel=&#8221;prev&#8221;/&gt; element. This is part of being RESTful: a representation of a resource provides links to other things.</p>
<p>At this point, I&#8217;ve walked through the first seven steps of the process. The remaining steps are to consider the typical course of events, and to consider error conditions. I&#8217;ll pick that up in the next post. After that, it will be time to start whipping up some code!</p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/OLIeNpYpFxM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/04/a-restful-chess-service-part-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/04/a-restful-chess-service-part-4/</feedburner:origLink></item>
		<item>
		<title>A RESTful chess service: part 3</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/RxUYDng7XNg/</link>
		<comments>http://blog.davidcassel.net/2010/03/a-restful-chess-service-part-3/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 11:35:41 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[chess]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=125</guid>
		<description><![CDATA[In part 2 of this series, I defined the data set and resources for my service. I&#8217;ve been following the procedure listed in RESTful Web Services for how to lay out the service. Here are those steps again:

Figure out the data set
Split the data set into resources
For each resource:
Name the resources with URIs
Expose a subset [...]]]></description>
			<content:encoded><![CDATA[<p>In part 2 of this series, I defined the data set and resources for my service. I&#8217;ve been following the procedure listed in <a href="http://www.amazon.com/gp/product/0596529260?ie=UTF8&amp;tag=shastuonl-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596529260" target="_blank">RESTful Web Services</a> for how to lay out the service. Here are those steps again:</p>
<ol>
<li>Figure out the data set</li>
<li>Split the data set into resources</li>
<p>For each resource:</p>
<li>Name the resources with URIs</li>
<li>Expose a subset of the uniform interface</li>
<li>Design the representation(s) accepted from the client</li>
<li>Design the representation(s) served to the client</li>
<li>Integrate this resource into existing resources, using hypermedia links and forms</li>
<li>Consider the typical course of events</li>
<li>Consider error conditions</li>
</ol>
<h2>Naming the Resources</h2>
<p>I&#8217;ve finished the first two steps, and in doing so I identified Events, Players, Games, and search as resources that I want to expose through the service. Let&#8217;s take a look at the Games resource first. I need to decide how I will build the URI for a game. Let&#8217;s take another look at the <a href="http://en.wikipedia.org/wiki/Portable_Game_Notation" target="_blank">PGN</a> headers for my sample game again:</p>
<div id="_mcePaste">[Event "First Saturday Quads"]</div>
<div id="_mcePaste">[Site "West Chester Chess Club"]</div>
<div id="_mcePaste">[Date "2003.02.01"]</div>
<div id="_mcePaste">[Round "1"]</div>
<div id="_mcePaste">[White "Joe Demetrick"]</div>
<div id="_mcePaste">[Black "David Cassel"]</div>
<div id="_mcePaste">[Result "1/2-1/2"]</div>
<div id="_mcePaste">[WhiteElo "1337"]</div>
<div id="_mcePaste">[ECO "D13b"]</div>
<p>Of these fields, I believe you would need to specify Event, Site, Date, Round, White, and Black to be sure you&#8217;ve uniquely identified a game. This would cover cases where two players are playing a series of matches, with multiple games in the same day (I think this would be an unusual case, but it&#8217;s best to be sure). I can picture a couple different ways to identify this game with a URI. A very transparent way to do it would be to include each piece needed for uniqueness as a path variable:</p>
<p>/games/First+Saturday+Quads/West+Chester+Chess+Club/2003.02.01/1/Joe+Demetrick/David+Cassel</p>
<p>Another approach, which is a bit more compact, is to take the hash of the needed values and use that:</p>
<p>/games/372fa3184dc56e2910cc91195baccb4b</p>
<p>If I could count on each game having a game id field, I could just use that, of course, but that does not appear to be a widely used field, so let&#8217;s think about the two options I&#8217;ve laid out. Clearly, the first is more informative to a human reader. That&#8217;s handy, but there is something I&#8217;m not wild about with this scheme: the slashes typically imply a hierarchy; here, no such hierarchy is really there. The authors use other punctuation to deal with cases where there isn&#8217;t actually a hierarchy. For instance, when they establish URIs for maps, they separate the latitude and longitude values with commas instead of slashes. The slash-based structure implies some hierarchy where none really exists.</p>
<p>On the other hand, the hash certainly doesn&#8217;t imply an hierarchy. In fact, it&#8217;s completely impenetrable: all you know from looking at the URI is that it identifies one particular game. Let&#8217;s think about how this service might be used. Picture doing a search and getting back a list of games. If you&#8217;re building an application that will present this list to the user, you won&#8217;t want to just give a list of hashes. You&#8217;ll want your user to have some way to decide what links to click. Using the first approach gives a lot of information about the game. Using the second approach, conversely, before a system could present a list it would need to retrieve each of the individual games in order to get the basic metadata.  Because it will be more helpful for building applications around the service, I&#8217;m going to go with the more descriptive URI.</p>
<h2>Exposing a Subset of the Uniform Interface</h2>
<p>The Uniform Interface refers to the set of HTTP methods. The most commonly used are <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3" target="_blank">GET</a>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5" target="_blank">POST</a>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6" target="_blank">PUT</a>, and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7" target="_blank">DELETE</a>. The protocol also supports <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4" target="_blank">HEAD</a>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2" target="_blank">OPTIONS</a>, <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.8" target="_blank">TRACE</a>, and <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.9" target="_blank">CONNECT</a>, but my service will not support any of these. In a nutshell, GET is used to retrieve a resource&#8217;s representation, POST  and PUT are used to create and update resources, and DELETE removes a resource. For the use cases I&#8217;ve described, there is only one way data changes through my service: a tournament director uploads a game. The way I will support this is to let the TD POST a game to /games/. Doing so will return the URI of the game. I will also allow a TD to PUT to a particular game URI, replacing the previous resource, as a way of correcting mistakes, as well as DELETE to simply remove a game.</p>
<p>I want to let users retrieve games, of course, or this service wouldn&#8217;t be all that useful. As such, I&#8217;ll support GET on a game to return a representation of that game. Here, I&#8217;ll throw in a little wrinkle: I want to offer the PGN version of the game, as that&#8217;s the standard representation, but I also want to offer an XML version, to be machine friendly. One of the hallmarks of a RESTful service is links between various resources. PGN doesn&#8217;t typically have links, but my XML representation will. With this in mind, I&#8217;ll make one change the URI used to retrieve a game: I&#8217;ll add an extension, which must be either .xml or .pgn.</p>
<h2>Designing the Representation Accepted from the Client</h2>
<p>Although my service will offer two representations for a game, I&#8217;ll only accept one from the client: the PGN standard. My service will expect to find the fields used to construct the URI; any other fields will be stored too.</p>
<h2>Designing the Representations Served to the Client</h2>
<p>The PGN representation needs no design work: when requested, a PGN representation will follow the standard format. The XML representation will take a little bit of thought, however.</p>
<pre>&lt;game&gt;
  &lt;headers&gt;
    &lt;Event&gt;First Saturday Quads&lt;/Event&gt;
    &lt;Site&gt;West Chester Chess Club&lt;/Site&gt;
    &lt;Date&gt;2003-02-01&lt;/Date&gt;
    &lt;Round&gt;1&lt;/Round&gt;
    &lt;White&gt;Joe Demetrick&lt;/White&gt;
    &lt;Black&gt;David Cassel&lt;/Black&gt;
    &lt;Result&gt;1/2-1/2&lt;/Result&gt;
    &lt;WhiteELO&gt;1337&lt;/WhiteELO&gt;
    &lt;ECO&gt;D13b&lt;/ECO&gt;
  &lt;/headers&gt;
  &lt;moves&gt;
    &lt;move num="1" color="w"&gt;d4&lt;/move&gt;
    &lt;move num="1" color="b"&gt;d5&lt;/move&gt;
    &lt;move num="1" color="w"&gt;c4&lt;/move&gt;
    &lt;move num="1" color="b"&gt;c6&lt;/move&gt;
    ...
  &lt;/moves&gt;
&lt;/game&gt;</pre>
<p>So far, this looks like an XMLized version of the PGN, with the one exception that I changed the date from 2003.02.01 to 2003-02-01. This simple change is to make the date a <a href="http://www.w3schools.com/Schema/schema_dtypes_date.asp" target="_blank">valid XML date</a>. I&#8217;ll make a couple more changes in the next section.</p>
<p>One last comment before we move on, however. I took a quick look for XML representations of chess games. It seems none have caught on, simply because PGN has been so successful at capturing the information. So why am I bothering? Two reasons: 1) to provide the links that a good RESTful service needs to connect the resources, and 2) because for this exercise, I want to show multiple representations.</p>
<h2>Integrate the Resource into Existing Resources</h2>
<p>One of the key elements of a RESTful service is links to guide a consuming application from resource to resource. PGN doesn&#8217;t provide a way to do that, but our XML representation can. Let&#8217;s add a few changes:</p>
<pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;">&lt;game&gt;
  &lt;link rel="alternate" type="application/x-chess-pgn"
    href="/games/First+Saturday+Quads/West+Chester+Chess+Club/2003.02.01/1/Joe+Demetrick/David+Cassel.pgn"/&gt;
  &lt;headers&gt;
    &lt;Event&gt;
      &lt;nameFirst Saturday Quads&lt;/name&gt;
      &lt;link uri="/events/First+Saturday+Quads"/&gt;
    &lt;/Event&gt;
    &lt;Site&gt;West Chester Chess Club&lt;/Site&gt;
    &lt;Date&gt;2003-02-01&lt;/Date&gt;
    &lt;Round&gt;1&lt;/Round&gt;
    &lt;White&gt;
      &lt;name&gt;Joe Demetrick&lt;/name&gt;
      &lt;link uri="/players/Joe+Demetrick"/&gt;
    &lt;/White&gt;
    &lt;Black&gt;
      &lt;name&gt;David Cassel&lt;/name&gt;
      &lt;link uri="/players/David+Cassel"/&gt;
    &lt;/Black&gt;
    &lt;Result&gt;1/2-1/2&lt;/Result&gt;
    &lt;WhiteELO&gt;1337&lt;/WhiteELO&gt;
    &lt;ECO&gt;D13b&lt;/ECO&gt;
  &lt;/headers&gt;
  &lt;moves&gt;
    &lt;move num="1" color="w"&gt;d4&lt;/move&gt;
    &lt;move num="1" color="b"&gt;d5&lt;/move&gt;
    &lt;move num="1" color="w"&gt;c4&lt;/move&gt;
    &lt;move num="1" color="b"&gt;c6&lt;/move&gt;
    ...
  &lt;/moves&gt;
&lt;/game&gt;</pre>
<p>For this step, I needed to jump ahead a bit and define the URIs for events and players. In most organizations, players would likely be given a unique id, which I would certainly want to use in the players URIs to avoid name collisions. Since PGN does typically use names, though, I&#8217;m going to stick with that for this exercise.</p>
<p>This post is getting a bit long, so I&#8217;m going to wrap this one up. In the next post, I&#8217;ll take a look at the representations for events and players as well as looking at seach.</p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/RxUYDng7XNg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/03/a-restful-chess-service-part-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/03/a-restful-chess-service-part-3/</feedburner:origLink></item>
		<item>
		<title>A RESTful chess service: part 2</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/QH1y6_gpw6Y/</link>
		<comments>http://blog.davidcassel.net/2010/02/a-restful-chess-service-part-2/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 15:18:24 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[chess]]></category>
		<category><![CDATA[resources]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=118</guid>
		<description><![CDATA[In part 1 of this series, I laid out my goals for a RESTful chess service, based on the RESTful Web Services book from the O&#8217;Reilly series. The authors present a procedure for designing services, the first two of which are:

Figure out the data set
Split the data set into resources

The use cases I&#8217;m looking to [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://blog.davidcassel.net/2010/02/a-restful-chess-service-part-1/">part 1</a> of this series, I laid out my goals for a RESTful chess service, based on the <a href="http://www.amazon.com/gp/product/0596529260?ie=UTF8&amp;tag=shastuonl-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596529260" target="_blank">RESTful Web Services</a> book from the O&#8217;Reilly series. The authors present a procedure for designing services, the first two of which are:</p>
<ol>
<li>Figure out the data set</li>
<li>Split the data set into resources</li>
</ol>
<p>The use cases I&#8217;m looking to support are chess tournament directors (TD) reporting games during events and people searching for events, players, and games. That identifies my three major parts of the data set right there. There are other elements I could use. Chess has a standard notation for describing a game called <a href="http://en.wikipedia.org/wiki/Portable_Game_Notation" target="_blank">PGN</a>. Here&#8217;s an example from a small tournament I played in years ago:</p>
<div id="_mcePaste">[Event "First Saturday Quads"]</div>
<div id="_mcePaste">[Site "West Chester Chess Club"]</div>
<div id="_mcePaste">[Date "2003.02.01"]</div>
<div id="_mcePaste">[Round "1"]</div>
<div id="_mcePaste">[White "Joe Demetrick"]</div>
<div id="_mcePaste">[Black "David Cassel"]</div>
<div id="_mcePaste">[Result "1/2-1/2"]</div>
<div id="_mcePaste">[WhiteElo "1337"]</div>
<div id="_mcePaste">[ECO "D13b"]</div>
<div id="_mcePaste">1.d4 d5 2.c4 c6 3.Nf3 Nf6 4.cxd5 cxd5 5.Bf4 Bf5 6.e3 e6 7.Bb5+ Nbd7 8.O-O Qb6 9.Nc3 a6 10.Na4 Qxb5 11.Rc1 Be7 12.Ne5 Nxe5 13.Bxe5 O-O 14.b3 Rac8 15.Nb2 Ne4 16.g4 Nc3 17.Rxc3 Rxc3 18.gxf5 Rfc8 19.Qg4 f6 20.Nd1 Rc2 21.Bf4 exf5 22.Qxf5 Qc6 23.Kh1 Rxa2 24.Rg1 g6 25.Bh6 Bf8 26.Nc3 Qxc3 27.Qe6+ Kh8 28.Qxf6+ Kg8 29.Qe6+ 1/2-1/2</div>
<p>The format is pretty straightforward, I think. Metadata are at the top, followed by a list of moves in algebraic notation. If the move notation doesn&#8217;t make sense to you, don&#8217;t worry about it &#8212; that&#8217;s not important for this exercise.</p>
<p>This is a game I played in a small <a href="http://www.uschess.org/" target="_blank">USCF</a> event. You&#8217;ll notice the name of the event is &#8220;First Saturday Quads&#8221;. As you might guess, that&#8217;s not a unique name &#8212; other sites can have an event with the same name. Really it&#8217;s the combination of Event, Site, and Date that uniquely identify a particular tournament &#8212; and the date is a little dicey, since an event may span multiple days. This won&#8217;t be a problem for a TD uploading a game, as all the information is there. For search and browsing, I won&#8217;t have any explicit representation of a Tournament, although the service will allow a user to find all the games in a tournament.</p>
<p>The authors tell us that a resource is &#8220;anything interesting enough to be the target of a hypertext link.&#8221; They also list three kinds of resources web services commonly exposed.</p>
<h3>1) Predefined, one-off resources</h3>
<p>The given examples are top-level directories of available resources, or the home page of a web site. For my service, I will have a base resource that takes a collections approach, simply returning a list of links to the other resources available from the service.</p>
<h3>2) A resource for every object exposed through the service</h3>
<p>The objects I&#8217;ve decided to expose are events, players and games. Each event, player and game will be a unique resource available through the service. Events will be collections of games. We actually won&#8217;t be storing much information about players, only what is included in the game reports, so player resources will similarly be collections of games.</p>
<h3>3) Resources representing results of algorithms</h3>
<p>This service will define only one algorithm: search. The results will be collections of objects that match the search criteria. There will really be three ways to search, one for returning each type of object.</p>
<p>In the next part of this series, I&#8217;ll work through the remaining steps for the Game resource.</p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/QH1y6_gpw6Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/02/a-restful-chess-service-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/02/a-restful-chess-service-part-2/</feedburner:origLink></item>
		<item>
		<title>A RESTful chess service: Part 1</title>
		<link>http://feedproxy.google.com/~r/DavidCassel/~3/j2pUlQsQEDE/</link>
		<comments>http://blog.davidcassel.net/2010/02/a-restful-chess-service-part-1/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 15:28:14 +0000</pubDate>
		<dc:creator>Dave Cassel</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[chess]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.davidcassel.net/?p=110</guid>
		<description><![CDATA[I recently got a copy of RESTful Web Services, a book in the O&#8217;Reilly series that I read some time ago. I first read it when I was introduced to REST as an architectural style. It helped me get my head around a number of the concepts.
I decided that I want to refresh my memory [...]]]></description>
			<content:encoded><![CDATA[<p>I recently got a copy of <a href="http://www.amazon.com/gp/product/0596529260?ie=UTF8&amp;tag=shastuonl-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0596529260" target="_blank">RESTful Web Services</a>, a book in the O&#8217;Reilly series that I read some time ago. I first read it when I was introduced to REST as an architectural style. It helped me get my head around a number of the concepts.</p>
<p>I decided that I want to refresh my memory about some aspects of designing RESTfully and to explore how to build a RESTful service using MarkLogic Server, so this post is actually the introduction to a miniseries. The book has a suggested method for going through the design steps, so I&#8217;ll walk through those steps and the implementation over a few posts. I invite you to read along and see how the process unfolds.</p>
<p>First things first: I need to decide what need I&#8217;m trying to satisfy. Being a chess player, I decided to implement a service that would be used by a chess organization such as the <a href="http://uschess.org/" target="_blank">US Chess Federation</a>, <a href="http://www.fide.com/" target="_blank">FIDE</a> or the <a href="http://www.freechess.org/" target="_blank">Free Internet Chess Server</a>. These groups hold lots of tournaments, some of which are major international events while others are small events held by community chess clubs. In all cases, the tournament director needs to report the results to the organization, which will record the results and update players&#8217; ratings.</p>
<p>Besides reporting, my service will support searching. The service should provide representations of players, events, and individual games. We&#8217;ll return player and event information as XML, but we&#8217;ll give users the choice between XML and PGN, the standard for chess notation, for individual games. We&#8217;ll need some search capability, in addition to browsing.</p>
<p>RESTful Web Services gives a 9-step Generic ROA (Resource Oriented Architecture) Procedure:</p>
<ol>
<li> Figure out the data set</li>
<li>Split the data set into resources</li>
<p>For each resource:</p>
<li>Name the resources with URIs</li>
<li>Expose a subset of the uniform interface</li>
<li>Design the representation(s) accepted from the client</li>
<li>Design the representation(s) served to the client</li>
<li>Integrate this resource into existing resources, using hypermedia links and forms</li>
<li>Consider the typical course of events</li>
<li>Consider error conditions</li>
</ol>
<p>In this post, I&#8217;ve introduced the series and laid out roughly what I want to do. Next time I&#8217;ll tackle the first two steps in the process. See you then!</p>
<img src="http://feeds.feedburner.com/~r/DavidCassel/~4/j2pUlQsQEDE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.davidcassel.net/2010/02/a-restful-chess-service-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.davidcassel.net/2010/02/a-restful-chess-service-part-1/</feedburner:origLink></item>
	</channel>
</rss>
