<?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:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><description>Tales of a code samurai</description><title>Robust Software</title><generator>Tumblr (3.0; @gshutler)</generator><link>http://www.robustsoftware.co.uk/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/RobustSoftware" /><feedburner:info uri="robustsoftware" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://tumblr.superfeedr.com/" /><item><title>What Software Has in Common with Schrödinger’s Cat</title><description>&lt;a href="http://testobsessed.com/blog/2012/01/05/what-software-has-in-common-with-schrodingers-cat/"&gt;What Software Has in Common with Schrödinger’s Cat&lt;/a&gt;: &lt;p&gt;An interesting article exploring the relationship between quantum physics and continuous delivery.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;None of it is real until it is in the hands of actual users. I don’t mean someone who will poke at it a bit or evaluate it. And I don’t mean a proxy who will tell you if the users might like it. I mean someone who will use it for its intended purpose as part of their normal routine. The experience those users report is reality. Everything else is speculation.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=VKoe4u-mj4w:tc9ktM3gHqs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=VKoe4u-mj4w:tc9ktM3gHqs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=VKoe4u-mj4w:tc9ktM3gHqs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=VKoe4u-mj4w:tc9ktM3gHqs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=VKoe4u-mj4w:tc9ktM3gHqs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=VKoe4u-mj4w:tc9ktM3gHqs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=VKoe4u-mj4w:tc9ktM3gHqs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/VKoe4u-mj4w" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/VKoe4u-mj4w/17107984504</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/17107984504</guid><pubDate>Sun, 05 Feb 2012 19:50:00 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/17107984504</feedburner:origLink></item><item><title>Gain Trust and Create Change - LDNUG - Followup</title><description>&lt;p&gt;Last Monday I gave my talk &amp;#8220;Gain Trust and Create Change&amp;#8221; for the first time at the &lt;a href="http://www.dnug.org.uk/"&gt;London .NET user group&lt;/a&gt;. The guys at &lt;a href="http://skillsmatter.com/"&gt;Skills Matter&lt;/a&gt; &lt;a href="http://skillsmatter.com/podcast/open-source-dot-net/ldnug-trust-change"&gt;recorded the whole thing so you can watch it online&lt;/a&gt; if you missed it.&lt;/p&gt;
&lt;p&gt;I am reasonably pleased with how the presentation went. Watching it back was an uncomfortable experience but is very useful to feed into the next time I give this talk. Speaking of which, if you run a user group and would like me to give this talk get in touch.&lt;/p&gt;
&lt;p&gt;For those of you interested in buying the two books I mentioned during the talk, they are &lt;a href="http://pragprog.com/book/cfcar2/the-passionate-programmer"&gt;The Passionate Programmer&lt;/a&gt; and &lt;a href="http://pragprog.com/book/trevan/driving-technical-change"&gt;Driving Technical Change&lt;/a&gt;, both from &lt;a href="http://pragprog.com/"&gt;The Pragmatic Programmers&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d like to thank everyone who turned up, &lt;a href="https://twitter.com/#!/icooper"&gt;Ian Cooper&lt;/a&gt; for giving me the opportunity and Skills Matter for hosting.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Gh2_z5ohZpw:GBepIG1CUfY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Gh2_z5ohZpw:GBepIG1CUfY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Gh2_z5ohZpw:GBepIG1CUfY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Gh2_z5ohZpw:GBepIG1CUfY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Gh2_z5ohZpw:GBepIG1CUfY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Gh2_z5ohZpw:GBepIG1CUfY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Gh2_z5ohZpw:GBepIG1CUfY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Gh2_z5ohZpw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/Gh2_z5ohZpw/17089736929</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/17089736929</guid><pubDate>Sun, 05 Feb 2012 13:43:25 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/17089736929</feedburner:origLink></item><item><title>Heroku in Europe</title><description>&lt;p&gt;I &lt;a href="https://twitter.com/#!/gshutler/status/162123047673925632"&gt;tweeted yesterday&lt;/a&gt; (25th Jan 2012) to ask if anyone knew of a solution as convenient as &lt;a href="http://www.heroku.com/"&gt;Heroku&lt;/a&gt; but based in the UK or Europe.&lt;/p&gt;
&lt;p&gt;The reason I asked was at &lt;a href="http://uk.zopa.com/ZopaWeb/"&gt;Zopa&lt;/a&gt; we are thinking of migrating our front-end over to a Ruby stack and Heroku was the obvious option for hosting such a solution. However, as 95% or more of our traffic comes from the UK it doesn&amp;#8217;t make complete sense to host our website outside of the UK or Europe at worst.&lt;/p&gt;
&lt;p&gt;I got a lot of interest from Twitter as to whether I found anything but no suggestions of similar services based this side of the pond. At the same time I sent an email to Heroku&amp;#8217;s support asking if they had any plans to give an UK or European hosting option.&lt;/p&gt;
&lt;p&gt;Heroku got back to me yesterday evening and said they have no immediate plans for server resources outside the US but they are working on Safe Harbor certification if your concerns are of a more legal nature. They also confirmed that they are hosted within the US East region of AWS which is better than West for Europeans.&lt;/p&gt;
&lt;p&gt;Their suggested strategy is to use a CDN alongside Heroku so that the majority of your assets will come from a local source and only your dynamic content will come from the US.&lt;/p&gt;
&lt;p&gt;This probably rules out Heroku for us at Zopa as a CDN adds needless complexity for us given our traffic volumes and the fact that almost all of our traffic is from the same location. However, I thought I should knock a blog post together to share what I found.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=vkJVt_BpHSs:p6eASipGrWs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=vkJVt_BpHSs:p6eASipGrWs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=vkJVt_BpHSs:p6eASipGrWs:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=vkJVt_BpHSs:p6eASipGrWs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=vkJVt_BpHSs:p6eASipGrWs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=vkJVt_BpHSs:p6eASipGrWs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=vkJVt_BpHSs:p6eASipGrWs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/vkJVt_BpHSs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/vkJVt_BpHSs/16515762624</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/16515762624</guid><pubDate>Thu, 26 Jan 2012 10:01:06 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/16515762624</feedburner:origLink></item><item><title>Gain Trust and Create Change - LDNUG</title><description>&lt;p&gt;I&amp;#8217;m doing a talk at &lt;a href="http://skillsmatter.com/"&gt;Skills Matter&lt;/a&gt; on 30th January titled &amp;#8220;Gain Trust and Create Change&amp;#8221; for the &lt;a href="http://www.dnug.org.uk/"&gt;London .NET user group&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Registration has opened so &lt;a href="http://skillsmatter.com/event/open-source-dot-net/ldnug-trust-change"&gt;reserve yourself a place&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you run a user group and would like me to present this topic then &lt;a href="mailto:garry+gain-trust@robustsoftware.co.uk"&gt;drop me an email&lt;/a&gt; and I&amp;#8217;ll try and arrange something.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=OgPiUkwi90E:fHkMKcWbfR8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=OgPiUkwi90E:fHkMKcWbfR8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=OgPiUkwi90E:fHkMKcWbfR8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=OgPiUkwi90E:fHkMKcWbfR8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=OgPiUkwi90E:fHkMKcWbfR8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=OgPiUkwi90E:fHkMKcWbfR8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=OgPiUkwi90E:fHkMKcWbfR8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/OgPiUkwi90E" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/OgPiUkwi90E/15945572468</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/15945572468</guid><pubDate>Mon, 16 Jan 2012 14:12:27 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/15945572468</feedburner:origLink></item><item><title>DDD North - Introduction to Backbone.js</title><description>&lt;p&gt;Yesterday, I gave a presentation on &lt;a title="Backbone.js" href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt; at the inaugural &lt;a title="DDD North" href="http://www.developerdeveloperdeveloper.com/north/"&gt;DDD North&lt;/a&gt;. My thanks go out to &lt;a title="Andrew Westgarth's blog" href="http://www.andrewwestgarth.co.uk/blog"&gt;Andrew Westgarth&lt;/a&gt; and his team for organising it, it was a great event.&lt;/p&gt;
&lt;p&gt;I was a bit nervous as it was my first time speaking at a conference and I think it showed. I rattled through my presentation at break-neck speed, unfortunately finishing well under my allocated hour. &lt;a title="Niall Merrigan" href="http://twitter.com/nmerrigan"&gt;Niall Merrigan&lt;/a&gt; gave me some tips for sorting that out so I&amp;#8217;ll hopefully be more composed next time! &lt;/p&gt;
&lt;p&gt;I&amp;#8217;d like to thank everyone who showed up for my talk and look forward to receiving their feedback. The slides for my presentation are now &lt;a title="Presentation slides on Slideshare" href="http://www.slideshare.net/gshutler/introduction-to-backbonejs-ddd-north-9617777"&gt;up on Slideshare&lt;/a&gt; and the code I demonstrated is &lt;a title="DDD North demo application on Github" href="https://github.com/gshutler/dddnorth"&gt;available on Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
&lt;object id="__sse9617777" width="425" height="355"&gt;
&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ddd-north-111009090204-phpapp02&amp;amp;stripped_title=introduction-to-backbonejs-ddd-north-9617777&amp;amp;userName=gshutler"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed name="__sse9617777" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=ddd-north-111009090204-phpapp02&amp;amp;stripped_title=introduction-to-backbonejs-ddd-north-9617777&amp;amp;userName=gshutler" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;
&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;amp;c2=7400849&amp;amp;c3=1&amp;amp;c4=&amp;amp;c5=&amp;amp;c6="&gt;&lt;/script&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=aw6rFpHujyw:okx5vBoRRVc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=aw6rFpHujyw:okx5vBoRRVc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=aw6rFpHujyw:okx5vBoRRVc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=aw6rFpHujyw:okx5vBoRRVc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=aw6rFpHujyw:okx5vBoRRVc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=aw6rFpHujyw:okx5vBoRRVc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=aw6rFpHujyw:okx5vBoRRVc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/aw6rFpHujyw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/aw6rFpHujyw/11225991509</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/11225991509</guid><pubDate>Sun, 09 Oct 2011 15:05:00 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/11225991509</feedburner:origLink></item><item><title>Resources For, And How I Learnt Backbone.js</title><description>&lt;a href="http://lostechies.com/derickbailey/2011/09/13/resources-for-and-how-i-learned-backbone-js/"&gt;Resources For, And How I Learnt Backbone.js&lt;/a&gt;: &lt;p&gt;I was going to compile a similar list of resources for my upcoming &lt;a href="http://www.developerdeveloperdeveloper.com/north/ViewSession.aspx?SessionID=823"&gt;talk on backbone.js at DDD North&lt;/a&gt; but &lt;a href="https://twitter.com/#!/derickbailey"&gt;Derick Bailey&lt;/a&gt; beat me to it. Check it out.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=RHo1BadD5wg:NTG0cayJVqc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=RHo1BadD5wg:NTG0cayJVqc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=RHo1BadD5wg:NTG0cayJVqc:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=RHo1BadD5wg:NTG0cayJVqc:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=RHo1BadD5wg:NTG0cayJVqc:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=RHo1BadD5wg:NTG0cayJVqc:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=RHo1BadD5wg:NTG0cayJVqc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/RHo1BadD5wg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/RHo1BadD5wg/10199749408</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/10199749408</guid><pubDate>Wed, 14 Sep 2011 13:04:02 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/10199749408</feedburner:origLink></item><item><title>Finagle</title><description>&lt;a href="http://engineering.twitter.com/2011/08/finagle-protocol-agnostic-rpc-system.html"&gt;Finagle&lt;/a&gt;: &lt;p&gt;I came across Finagle a few weeks ago, it’s:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;&lt;em&gt;… a protocol-agnostic, asynchronous RPC system for the JVM that makes it easy to build robust clients and servers in Java, Scala, or any JVM-hosted language.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And they’ve now &lt;a href="http://engineering.twitter.com/2011/08/finagle-protocol-agnostic-rpc-system.html"&gt;written a blog post announcing it to the world&lt;/a&gt;. I had a skim over it before but it looks like they’ve added to the documentation since then.&lt;/p&gt;
&lt;p&gt;I’ve been looking for a framework for writing servers in Scala, the &lt;a href="http://scala.playframework.org/"&gt;Play framework&lt;/a&gt; is on my radar for web applications, and this looks like a great contender.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=wT2ulpiYn0s:iAhK2lOBf3U:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=wT2ulpiYn0s:iAhK2lOBf3U:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=wT2ulpiYn0s:iAhK2lOBf3U:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=wT2ulpiYn0s:iAhK2lOBf3U:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=wT2ulpiYn0s:iAhK2lOBf3U:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=wT2ulpiYn0s:iAhK2lOBf3U:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=wT2ulpiYn0s:iAhK2lOBf3U:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/wT2ulpiYn0s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/wT2ulpiYn0s/9369538248</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/9369538248</guid><pubDate>Thu, 25 Aug 2011 09:44:59 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/9369538248</feedburner:origLink></item><item><title>LMAX architecture - Martin Fowler</title><description>&lt;a href="http://martinfowler.com/articles/lmax.html"&gt;LMAX architecture - Martin Fowler&lt;/a&gt;: &lt;p&gt;I remember &lt;a title="InfoQ: LMAX - How to Do 100K TPS at Less than 1ms Latency" href="http://www.infoq.com/presentations/LMAX"&gt;watching one of the original presentations on this architecture&lt;/a&gt; a few months ago (no idea why I didn’t link to it at the time) and &lt;a title="Martin Fowler - The LMAX Architecture" href="http://martinfowler.com/articles/lmax.html"&gt;Martin’s article&lt;/a&gt; puts it into a format that’s easier to consume at your leisure.&lt;/p&gt;
&lt;p&gt;Really interesting approach!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=xfPp-BBcdlg:7K30r0e0d7o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=xfPp-BBcdlg:7K30r0e0d7o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=xfPp-BBcdlg:7K30r0e0d7o:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=xfPp-BBcdlg:7K30r0e0d7o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=xfPp-BBcdlg:7K30r0e0d7o:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=xfPp-BBcdlg:7K30r0e0d7o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=xfPp-BBcdlg:7K30r0e0d7o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/xfPp-BBcdlg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/xfPp-BBcdlg/7571992596</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/7571992596</guid><pubDate>Wed, 13 Jul 2011 14:30:37 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/7571992596</feedburner:origLink></item><item><title>The Most Important Code Isn't Code</title><description>&lt;a href="http://zachholman.com/posts/documentation/"&gt;The Most Important Code Isn't Code&lt;/a&gt;: &lt;p&gt;I cannot stress how much I agree with this. I’ve come to exactly the same conclusions as Zach in the last year myself. I wish I had written this post myself!&lt;/p&gt;
&lt;p&gt;Here are my highlights:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Documentation is the best way to communicate your thoughts to yourself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Forcing myself first to consider the API, the interface, and the end result led to a clarity that inspired less code and a more impactful project.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;It improves the clarity of my code. I get more done in less lines.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;But documenting your code is cool as hell. More importantly, it makes me feel more confident about my own code. &lt;/p&gt;
&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Mg4B2Y33C8Q:ys_H5T8DwTE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Mg4B2Y33C8Q:ys_H5T8DwTE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Mg4B2Y33C8Q:ys_H5T8DwTE:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Mg4B2Y33C8Q:ys_H5T8DwTE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=Mg4B2Y33C8Q:ys_H5T8DwTE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Mg4B2Y33C8Q:ys_H5T8DwTE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=Mg4B2Y33C8Q:ys_H5T8DwTE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/Mg4B2Y33C8Q" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/Mg4B2Y33C8Q/6317957725</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/6317957725</guid><pubDate>Wed, 08 Jun 2011 13:24:44 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/6317957725</feedburner:origLink></item><item><title>"There’s a whole school of thought that quantity of features is directly proportional to what you can..."</title><description>“There’s a whole school of thought that quantity of features is directly proportional to what you can charge for software. While clearly this is true in practice, that doesn’t mean that it’s not incredibly stupid. Every new feature makes your software more complex to use.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;&lt;a href="http://www.jemery.com/2011/06/01/how-to-keep-your-software-awesome/"&gt;“How to keep your software awesome” by Jesse Emery&lt;/a&gt;&lt;/em&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ORHM4ElofGs:rsxuStJtBF8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=ORHM4ElofGs:rsxuStJtBF8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ORHM4ElofGs:rsxuStJtBF8:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ORHM4ElofGs:rsxuStJtBF8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=ORHM4ElofGs:rsxuStJtBF8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ORHM4ElofGs:rsxuStJtBF8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ORHM4ElofGs:rsxuStJtBF8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/ORHM4ElofGs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/ORHM4ElofGs/6110260471</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/6110260471</guid><pubDate>Thu, 02 Jun 2011 17:28:00 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/6110260471</feedburner:origLink></item><item><title>GiveCamp UK</title><description>&lt;p&gt;This morning I signed up for &lt;a title="GiveCamp UK" href="http://www.givecamp.org.uk/"&gt;GiveCamp UK&lt;/a&gt;. It is an event taking place this October in London where people involved in the software industry are donating a weekend of their free time to help charities with the IT needs. &lt;/p&gt;
&lt;p&gt;&lt;iframe src="http://player.vimeo.com/video/8474638?title=0&amp;amp;byline=0&amp;amp;portrait=0" width="600" height="338" frameborder="0"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://vimeo.com/8474638"&gt;What is GiveCamp?&lt;/a&gt; from &lt;a href="http://vimeo.com/givecamp"&gt;givecamp&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you can spare the time then &lt;a title="GiveCamp UK volunteer page" href="http://www.givecamp.org.uk/volunteer"&gt;sign up as a volunteer&lt;/a&gt; or if you work for a charity who could use some help &lt;a title="GiveCamp UK charity page" href="http://www.givecamp.org.uk/charity"&gt;submit a proposal&lt;/a&gt;. I have no doubt it is going to be a great weekend which will make a real difference to several charities.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=D9kC97Wriqc:KCBxKP-SJ60:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=D9kC97Wriqc:KCBxKP-SJ60:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=D9kC97Wriqc:KCBxKP-SJ60:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=D9kC97Wriqc:KCBxKP-SJ60:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=D9kC97Wriqc:KCBxKP-SJ60:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=D9kC97Wriqc:KCBxKP-SJ60:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=D9kC97Wriqc:KCBxKP-SJ60:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/D9kC97Wriqc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/D9kC97Wriqc/5924765284</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/5924765284</guid><pubDate>Sat, 28 May 2011 09:38:00 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/5924765284</feedburner:origLink></item><item><title>Tags are magic! - Guardian</title><description>&lt;a href="http://www.guardian.co.uk/info/developer-blog/2011/jan/10/tags-are-magic-1"&gt;Tags are magic! - Guardian&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ICvkczqriOE:m3WqpR7d7Nk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=ICvkczqriOE:m3WqpR7d7Nk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ICvkczqriOE:m3WqpR7d7Nk:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ICvkczqriOE:m3WqpR7d7Nk:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=ICvkczqriOE:m3WqpR7d7Nk:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ICvkczqriOE:m3WqpR7d7Nk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=ICvkczqriOE:m3WqpR7d7Nk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/ICvkczqriOE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/ICvkczqriOE/3198353382</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/3198353382</guid><pubDate>Wed, 09 Feb 2011 13:39:41 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/3198353382</feedburner:origLink></item><item><title>Pragmatic web service design</title><description>&lt;p&gt;Web services are a crucial part of most solutions nowadays, I spend a  significant portion of my time designing and writing them and I have  read a lot about them to make them better, faster and more resilient  each time. This is a summary of how I approach web service design and  the things I bear in mind.&lt;/p&gt;
&lt;h2 id="protocols_and_content_types"&gt;Protocols and content types&lt;/h2&gt;
&lt;p&gt;Unless you require extreme performance from your service then use the  most compatible technologies available. Today that means HTTP, JSON and  HTML forms. The lowest common denominator in any solution is usually  Javascript in the browser. This shapes all your decisions about how to  expose your service. HTTP, JSON and HTML forms are the easiest things to  work with in Javascript and they are well supported in other languages.  XML is an option but JSON is a more efficient transport medium and much  easier to work with in Javascript.&lt;/p&gt;
&lt;p&gt;Before you write a web service make sure to learn HTTP inside and  out. It is a powerful protocol that solves many more problems than most  people realise. I would recommend &lt;a title="RESTful Web Services" href="http://oreilly.com/catalog/9780596529260"&gt;RESTful web services&lt;/a&gt; as a starting point, it demonstrates how to create a web service that  is sympathetic to HTTP and there is a useful glossary in the back. This  is not going to be another post about REST but if you know about it  already there will be some familiar concepts.&lt;/p&gt;
&lt;p&gt;Using the correct HTTP code is important, think of it as a well  established domain-specific language for what the server thought of your  request. It removes the need to duplicate something like a response  code within the body of the response. A caveat on exploiting all that  HTTP gives you is to avoid 300 errors as browsers will redirect the  whole page even when it is a response to an AJAX request.&lt;/p&gt;
&lt;p&gt;For sending and receiving data I recommend HTML form values in, JSON  out. You may want to send requests in as JSON instead and that’s not a  bad choice, I just find HTML forms easier. However, I would recommend  using the same input and output content type for requests across your  whole API whenever possible. It makes it easier to consume an API when  you do not have to think what format a given method accepts and responds  with.&lt;/p&gt;
&lt;p&gt;Avoid supporting several content types, particularly for the first  couple of releases. You will end up iterating over your service during  initial development and having to maintain compatibility for several  content types will be adding wasteful overhead at this point. Get it  shipped with one pair of content types then look to fix your bugs,  harden your API and learn from real usage patterns. Put this into the  next version and repeat. Once things stabilise you can evaluate whether  support for several content types is needed based upon real world  requests without it being such a burden as your API goes through the  churn of first contact with the real world.&lt;/p&gt;
&lt;h2 id="core_design_considerations"&gt;Core design considerations&lt;/h2&gt;
&lt;p&gt;A lot of the considerations are identical to those of &lt;a title="How To Design A Good API and Why it Matters" href="http://www.youtube.com/watch?v=aAb7hSCtvGw"&gt;designing any API&lt;/a&gt; but there are some additional ones that are specific to web services as they involve transmission over a network.&lt;/p&gt;
&lt;h3 id="log_everything"&gt;Log everything&lt;/h3&gt;
&lt;p&gt;It should be obvious but you need to log every request that comes in.  You may need to replicate an issue that is a result of several  requests, without logging this will be difficult. You want to easily  answer the question “what was the consumer doing at the time?”. Logs  will also allow you to monitor usage, response times and other useful  metrics. As your first attempt at an API is no more than an informed  guess you need to be collecting metrics in order to make an educated  decision about what to do next.&lt;/p&gt;
&lt;h3 id="comply_with_the_expected_behaviour_of_http"&gt;Comply with the expected behaviour of HTTP&lt;/h3&gt;
&lt;p&gt;There are several expected behaviours with HTTP such as GET not  producing side effects and PUT and DELETE requests being idempotent.  This all comes from knowing HTTP as previously encouraged. Being able to  justify a design decision by referring to RFCs is awesome.&lt;/p&gt;
&lt;h3 id="less_methods_returning_more_data"&gt;Less methods returning more data&lt;/h3&gt;
&lt;p&gt;The biggest bottleneck in communicating with a server is no longer  the size of the data being communicated, it is in establishing  connections. This is particularly true for internal services. The common  bottleneck with web services is the number of concurrent requests they  can serve, not the amount of data being transferred. You want to aim to  have less methods but return more data from them, therefore reducing the  number of requests consumers need to make. Having less methods also  makes it easier for the consumer to make the right choice.&lt;/p&gt;
&lt;p&gt;Imagine everything a consumer is likely to want to display as a  result of making the request and give it to them. The only thing you  need to be careful of is your internal implementation bleeding into your  API. You do not want to expose yourself in public, especially early on.  Following this advice makes it likely the consumer will get all the  data they need in one request rather than making a separate request for  each part. This reduces the surface area of your API which has several  great benefits:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;as a developer I have less methods to maintain&lt;/li&gt;
&lt;li&gt;as a consumer I have a lower cognitive load, I might even be able to memorise your API&lt;/li&gt;
&lt;li&gt;as an administrator less requests helps me with caching and usually  means I can use less hardware, improving service and making scaling up  cheaper&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;In terms of web service surface area and required requests, less is definitely more.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This may seem to contradict my recommendation of using JSON but  choosing a more efficient protocol when there is no compelling reason  not to is foolish.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="highlander_principle"&gt;Highlander principle&lt;/h3&gt;
&lt;p&gt;There should be one, and only one, way to do something. Not only does  it save you effort, it makes things easier for the consumer. Sometimes  this may mean that one action requires several requests but this is less  confusing in the long run than creating a specific method for every  action. It is generally acceptable that the solution is good enough,  performing several simple steps is cognitively easier than wading  through a sea of methods to find the one intended for your task.&lt;/p&gt;
&lt;p&gt;Again I may seem to be contradicting myself as this goes againsts the  idea of trying to reduce the number of connections required to do  something and it does to some extent. However, when you consider most  systems are at least 80% reads, that this situation usually applies to  writes and that this should not be a regularly occurring problem if you  have modelled the domain correctly then it should be a drop in the ocean  of the general usage of the API.&lt;/p&gt;
&lt;p&gt;Any method you add on a hunch as to what future use will be you will  have to support for the lifetime of the API. It is better to wait until  you have real statistics and use-cases to work from than to increase the  surface area of your API speculatively. If an action requiring several  requests becomes common practice then you can add a method to simplify  it and you will be certain that it is adding value to your code base and  consumers.&lt;/p&gt;
&lt;h3 id="give_people_urls"&gt;Give people URLs&lt;/h3&gt;
&lt;p&gt;Whenever possible provide URLs to the consumer, do not make them work  them out. Every URL a consumer has to create is a support call waiting  to happen. When someone has to create a URL it is likely your internals  are bleeding into your API. Once someone else is creating a URL you can  never change that URL and that restricts refactoring and scaling  options. When you create URLs for your consumers you can rename them and  point them towards different servers to name just two options that  would be closed to you the second you are not in control of your URLs.&lt;/p&gt;
&lt;h3 id="version_from_the_outset"&gt;Version from the outset&lt;/h3&gt;
&lt;p&gt;There will be several versions of your web service. Think about  identifying the schema of your data when it is returned, think about how  you will host several versions of the API as you cannot just switch one  on and the previous version off. It will happen and it will be  difficult to lever in at a later date, make it a solved problem.&lt;/p&gt;
&lt;h3 id="example__twitters_feed"&gt;Example - Twitter’s feed&lt;/h3&gt;
&lt;p&gt;Here’s the response for a single tweet from my timeline:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ { ...,
    "entities" : { "hashtags" : [  ],
        "urls" : [  ],
        "user_mentions" : [ { "id" : 1102,
              "id_str" : "1102",
              "indices" : [ 3,
                  10
                ],
              "name" : "David Ulevitch",
              "screen_name" : "davidu"
            } ]
      },
    "favorited" : false,
    "geo" : null,
    "id" : 34612066580955136,
    "id_str" : "34612066580955136",
    "in_reply_to_screen_name" : null,
    "in_reply_to_status_id" : null,
    "in_reply_to_status_id_str" : null,
    "in_reply_to_user_id" : null,
    "in_reply_to_user_id_str" : null,
    "place" : null,
    "retweet_count" : 10,
    "retweeted" : false,
    "retweeted_status" : { 
        ...,
        "id" : 34583191385935872,
        "id_str" : "34583191385935872",
        ...,
        "retweet_count" : 10,
        ...,
        "text" : "The last 5% of a project is always the worst half of a project. :-)",
        "truncated" : false,
        "user" : { "contributors_enabled" : false,
            "created_at" : "Sun Jul 16 02:30:23 +0000 2006",
            "description" : "Positively disruptive.  Started OpenDNS, ...",
            ...,
            "id" : 1102,
            "id_str" : "1102",
            ...,
            "profile_background_color" : "9BE5E9",
            "profile_background_image_url" : "http://a3.twimg.com/profile...jpg",
            ...
          }
      },
    "source" : "web",
    "text" : "RT @davidu: The last 5% of a project is always the worst half of a project. :-)",
    "truncated" : false,
    "user" : { "contributors_enabled" : false,
        "created_at" : "Thu May 29 20:25:50 +0000 2008",
        "description" : "Freelance software developer fond of Linux, ...",
        ...
      }
  } ]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see this contains everything about the tweet, including  which tweet was being retweeted, who they were, what their profile  preferences are, where their profile image is, everything you could want  really. As a consumer I don’t need to make at least two additional  request to retrieve the details for the involed users which would lead  to a N+1 load on the server.&lt;/p&gt;
&lt;p&gt;The only thing that sticks out to me as possibly being bad is the &lt;code&gt;id&lt;/code&gt; values, that smells of internals details leaking out. Instead they might use &lt;code&gt;user_url&lt;/code&gt; and instead give a URL for the user’s full profile and so forth. There  also doesn’t appear to be any mention of a version for the message but  they may handle versioning by using different URLs for different  versions of the API.&lt;/p&gt;
&lt;h2 id="things_to_bear_in_mind_during_implementation"&gt;Things to bear in mind during implementation&lt;/h2&gt;
&lt;h3 id="do_not_reinvent_the_wheel"&gt;Do not reinvent the wheel&lt;/h3&gt;
&lt;p&gt;For example, methods to achieve caching already exist which utilise  the caching mechanisms built into HTTP itself. Use these when possible  rather than reimplementing it yourself. &lt;a title="Squid" href="http://www.squid-cache.org/"&gt;Squid&lt;/a&gt; and &lt;a title="Varnish" href="http://www.varnish-cache.org/"&gt;Varnish&lt;/a&gt; are two open source software based solutions that are easy to set up. &lt;a title="Header field definitions, part of RFC2616" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html"&gt;Learn about the wide array of established HTTP headers available&lt;/a&gt;, it is rare that you need to create a custom header.&lt;/p&gt;
&lt;h3 id="comprehensive_documentation"&gt;Comprehensive documentation&lt;/h3&gt;
&lt;p&gt;Yes, even for internal use. If your API is not documented it will be  hard to use and under utilised. Without documentation you will spend a  lot of time explaining how you go about using your API when you could  tell a HTML file once and have that explain it to everyone.&lt;/p&gt;
&lt;p&gt;Use examples of performing a common task with your API on top of an  example for each method. Ideally the reader will be able to run these  examples as they read. Ask a designer to throw a template together for  you, it doesn’t need to be amazing but it will make reading your  documentation a more pleasurable experience.&lt;/p&gt;
&lt;h3 id="no_breaking_changes_ever"&gt;No breaking changes, ever&lt;/h3&gt;
&lt;p&gt;Once you’ve published it and it is exposed to the world, you cannot  change anything, ever. Not even fix bugs as people will have written  workarounds for them. You can add methods or return more data in  response but you must never alter what has been published before. People  will be relying on it and you will fuck them up.&lt;/p&gt;
&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;Writing an API is very hard&lt;/li&gt;
&lt;li&gt;Really learn HTTP&lt;/li&gt;
&lt;li&gt;Remove choices and complexity by using less content types and exposing less methods&lt;/li&gt;
&lt;li&gt;Reduce the quantity of requests by returning more data in responses&lt;/li&gt;
&lt;li&gt;Give URLs to the consumer, don’t let them create them&lt;/li&gt;
&lt;li&gt;Documentation, documentation, documentation&lt;/li&gt;
&lt;/ul&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fSaa9mxHbAA:PaMu1ogMLtU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=fSaa9mxHbAA:PaMu1ogMLtU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fSaa9mxHbAA:PaMu1ogMLtU:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fSaa9mxHbAA:PaMu1ogMLtU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=fSaa9mxHbAA:PaMu1ogMLtU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fSaa9mxHbAA:PaMu1ogMLtU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fSaa9mxHbAA:PaMu1ogMLtU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/fSaa9mxHbAA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/fSaa9mxHbAA/3163820769</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/3163820769</guid><pubDate>Mon, 07 Feb 2011 14:28:28 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/3163820769</feedburner:origLink></item><item><title>Nero - Me And You
I love this track and I noticed they’ve...</title><description>&lt;iframe width="400" height="225" src="http://www.youtube.com/embed/bE47er6qnqg?wmode=transparent&amp;autohide=1&amp;egm=0&amp;hd=1&amp;iv_load_policy=3&amp;modestbranding=1&amp;rel=0&amp;showinfo=0&amp;showsearch=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;strong&gt;Nero - Me And You&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I love this track and I noticed they’ve made a Tron inspired video for it!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=10ff9IShu5Y:1rRuExthv6M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=10ff9IShu5Y:1rRuExthv6M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=10ff9IShu5Y:1rRuExthv6M:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=10ff9IShu5Y:1rRuExthv6M:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=10ff9IShu5Y:1rRuExthv6M:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=10ff9IShu5Y:1rRuExthv6M:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=10ff9IShu5Y:1rRuExthv6M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/10ff9IShu5Y" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/10ff9IShu5Y/2727124720</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/2727124720</guid><pubDate>Thu, 13 Jan 2011 09:22:14 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/2727124720</feedburner:origLink></item><item><title>Cross-site XMLHttpRequest with CORS</title><description>&lt;a href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/"&gt;Cross-site XMLHttpRequest with CORS&lt;/a&gt;: &lt;p&gt;I was working on a personal project over the Christmas period and wanted to make cross-site requests from an AJAX client to an API.&lt;/p&gt;
&lt;p&gt;As the client and the API were hosted on different domains they violated the &lt;a title="Same origin policy - Wikipedia" href="http://en.wikipedia.org/wiki/Same_origin_policy"&gt;same origin policy&lt;/a&gt; implemented by almost all browsers. Modern browsers allow cross-site AJAX requests if the API allows &lt;a title="Cross-origin resource sharing - Wikipedia" href="http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing"&gt;cross-origin resource sharing (CORS)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The resources I found at the time on this were a little bare on details but I managed to piece it together and get something working. I was planning on writing a blog post about how to do it but now I know all the terminology I came across &lt;a title="Cross-site XMLHttpRequest with CORS" href="http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/"&gt;this complete article that explains CORS very well&lt;/a&gt;, linking to several useful resources.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=myt2NBaoJCM:Sf5ZYK7WCM0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=myt2NBaoJCM:Sf5ZYK7WCM0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=myt2NBaoJCM:Sf5ZYK7WCM0:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=myt2NBaoJCM:Sf5ZYK7WCM0:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=myt2NBaoJCM:Sf5ZYK7WCM0:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=myt2NBaoJCM:Sf5ZYK7WCM0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=myt2NBaoJCM:Sf5ZYK7WCM0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/myt2NBaoJCM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/myt2NBaoJCM/2608623727</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/2608623727</guid><pubDate>Wed, 05 Jan 2011 12:50:06 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/2608623727</feedburner:origLink></item><item><title>Why Rack should matter to .NET developers</title><description>&lt;p&gt;There’s been a lot of talk in the .NET community about &lt;a title="Sinatra homepage" href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; clones, namely &lt;a title="Nancy homepage" href="https://github.com/thecodejunkie/Nancy"&gt;Nancy&lt;/a&gt; and &lt;a title="Nina homepage" href="http://jondot.github.com/nina/"&gt;Nina&lt;/a&gt; in recent times but there are &lt;a title="Tweet by Keith Dahlby listing several .NET Sinatra clones" href="http://twitter.com/dahlbyk/status/9070232853286913"&gt;several others as well&lt;/a&gt;. Unfortunately, all these frameworks are missing the underlying reason that &lt;a title="Sinatra homepage" href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; is awesome and that is &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;. &lt;a title="Sinatra homepage" href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; packs a hell of a lot of functionality yet weighs in at &lt;a title="Sinatra base.rb on Github" href="https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb"&gt;1198 lines of code including documentation&lt;/a&gt;. The main reason for that is the fact it is building on top of &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; which has allowed the authors to concentrate on creating a framework  without having to worry about the details of dealing with server  requests. So what is &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;, why you should care and why does it matter to you as a .NET developer.&lt;/p&gt;
&lt;h3 id="what_is_rack"&gt;What is Rack?&lt;/h3&gt;
&lt;p&gt;&lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; is a layer of abstraction which sits between servers and frameworks.  What it brings as a result is greater interoperability between HTTP  server implementations and web frameworks. As the author of a HTTP  server if you get your server to speak &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; you can now host applications written in several Ruby frameworks, &lt;a title="Sinatra homepage" href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; and &lt;a title="Ruby on Rails homepage" href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt; being two of the most well known. As a web framework author if you get your framework to speak &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; your application can now be hosted on several types of HTTP server.&lt;/p&gt;
&lt;p&gt;This greatly reduces the barrier to adoption for both servers and  frameworks. Rather than the previous method of having to write an  adapter for each server or framework you wished to be compatible with;  you are now able to write a single adapter for &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; and be hosted by several types of server or host multiple frameworks depending on which side of the boundary you are sitting.&lt;/p&gt;
&lt;p&gt;Needless to say, the Ruby community has jumped all over this. It  removes the duplication of effort that was previously required to get  the same level of interoperability allowing the Ruby community to focus  on innovation. For example, &lt;a title="Sinatra homepage" href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; did not exist before &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;. &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; didn’t make &lt;a title="Sinatra homepage" href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; possible but it made it much easier to create. Dealing with HTTP  servers had been done for them. They could instead focus on turning  requests into responses in an elegant manner.&lt;/p&gt;
&lt;h3 id="why_should_you_care"&gt;Why should you care?&lt;/h3&gt;
&lt;p&gt;First, lets talk about testing. &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; is entirely Ruby based at its core. That means that when you are  testing your application you can mimic a real HTTP request being invoked  and see what response your application turns that into. Let me show you  an example of that being done using &lt;a title="RSpec homepage" href="http://relishapp.com/rspec"&gt;RSpec&lt;/a&gt; against &lt;a title="Example Sinatra application on Github" href="https://github.com/gshutler/why_rack/blob/master/server.rb"&gt;a simple Sinatra application&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;get '/hello/:person' do |person|
  "Hello, #{person}"
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can &lt;a title="Example Sinatra application integration specification on Github" href="https://github.com/gshutler/why_rack/blob/master/simple_spec.rb"&gt;test how that application will respond to a HTTP request&lt;/a&gt; using &lt;a title="RSpec homepage" href="http://relishapp.com/rspec"&gt;RSpec&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe Server, 'making a hello request' do
  include Rack::Test::Methods
  
  let(:app) {subject}
  
  describe 'saying hello to world' do
    before do
      get '/hello/world'
    end
    
    it 'should respond "Hello, world"' do
      last_response.body.should == 'Hello, world'
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;I have commented the &lt;a title="Full example Sinatra application and integration specification on Github" href="https://github.com/gshutler/why_rack"&gt;full source for these examples up on Github&lt;/a&gt; if you want further explanation of what is happening here.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We’ve just written an integration test for our application without  having to deploy to a server or create our own abstraction of HTTP. This  same type of test will work for any application written using a  Rack-based framework. Just think of how painful the same thing is in  .NET currently. Not only does &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; give us greater interoperability between servers and frameworks, it gives us a way to test them easily as well.&lt;/p&gt;
&lt;p&gt;&lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; also has the concept of &lt;a title="List of available Rack middleware" href="https://github.com/rack/rack/wiki/List-of-Middleware"&gt;middleware&lt;/a&gt;. These are modules built on top of &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; that can then be utilised by any application based upon &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;. This again reduces duplication of effort within the community. Things that can be implemented in the &lt;a title="Rack homepage" href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt; layer, for example &lt;a title="Caching middleware for Rack" href="https://github.com/rtomayko/rack-cache"&gt;caching&lt;/a&gt;, are and that removes the need for functional clones for each Rack-based framework that wants the same functionality.&lt;/p&gt;
&lt;h3 id="why_it_matters_to_you_as_a_net_developer"&gt;Why it matters to you as a .NET developer&lt;/h3&gt;
&lt;p&gt;If you’re thinking “well I don’t do integration tests, write HTTP  servers or web frameworks, why should I care?” I’ll tell you why you  should. For the frameworks you use, a .NET equivalent to Rack would  eliminate a large amount of tedious and brittle code that adds no direct  value to a framework. This would allow the developers of frameworks to  focus their time on refinement giving you more powerful and stable tools  to work with. You may not use it yourself but you will benefit from its  existence within .NET.&lt;/p&gt;
&lt;p&gt;A .NET equivalent to Rack would open the door for a whole new  generation of web frameworks to be written. The barrier for writing a  quality web framework would be lowered as the nuts and bolts of request  and response handling would be a solved problem. We could see some real  innovation in .NET rather than a mass of clones of frameworks from other  languages.&lt;/p&gt;
&lt;p&gt;The door would also be opened for existing servers, such as &lt;a title="Apache server homepage" href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt;,  to be used for hosting .NET applications and enable entirely new  servers to be created. IIS would have competitors. This alone makes it  worthwhile. It would make the choice of .NET as a platform less tied, if  at all, to choosing Microsoft as a vendor. Even more so than &lt;a title="Mono project homepage" href="http://www.mono-project.com/Main_Page"&gt;Mono&lt;/a&gt; does today, particularly in the web space.&lt;/p&gt;
&lt;p&gt;There is a &lt;a title="Google Group for discussing the implementation of a standard HTTP abstraction for .NET" href="http://groups.google.com/group/net-http-abstractions"&gt;discussion going on right now about creating or choosing a single, common abstraction around HTTP, like Rack, for .NET&lt;/a&gt;.  Get involved in this discussion and contribute some of your time. This  is an opportunity to vastly improve the .NET ecosystem. We cannot afford  to miss it.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=rWOqWeg3Wdg:w2yAUb_DYTQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=rWOqWeg3Wdg:w2yAUb_DYTQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=rWOqWeg3Wdg:w2yAUb_DYTQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=rWOqWeg3Wdg:w2yAUb_DYTQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=rWOqWeg3Wdg:w2yAUb_DYTQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=rWOqWeg3Wdg:w2yAUb_DYTQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=rWOqWeg3Wdg:w2yAUb_DYTQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/rWOqWeg3Wdg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/rWOqWeg3Wdg/2131023052</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/2131023052</guid><pubDate>Tue, 07 Dec 2010 09:15:17 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/2131023052</feedburner:origLink></item><item><title>Use integration tests when working in a new language</title><description>&lt;p&gt;This is in some respects a &lt;a title="Simple tools and fundamental principles" href="http://www.robustsoftware.co.uk/post/1609359955/simple-tools-fundamental-principles"&gt;follow up to my previous post&lt;/a&gt; in that it has been triggered by &lt;a title="Adgistics" href="http://www.adgistics.com/"&gt;our&lt;/a&gt; internal project in Ruby. When working in Ruby I consciously lean towards integration tests. &lt;a title="Sinatra" href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; and &lt;a title="Sequel" href="http://sequel.rubyforge.org/"&gt;Sequel&lt;/a&gt; make this really as using rack-test and running against an in-memory SQLite database it is easy to simulate a full conversation of HTTP requests and they run reasonably quickly too.&lt;/p&gt;
&lt;p&gt;How does this relate to learning a new language? When writing anything in a new language you will make mistakes. You are likely to structure your application poorly. At a minimum you will find there is a much better way of achieving the same result. If you have based your work on unit tests you will have a straight-jacket tying your to your code making the effort to heavily refactor it much greater than it needs to be. Tests will need to be moved, rewritten, thrown away and renamed. However, when you use integration tests you are only verifying the behaviour of the whole system not its moving parts. This means you can replace the internals of your application entirely and your integration tests will not need to be changed and will ensure you have a system that still behaves the same as it did before.&lt;/p&gt;
&lt;p&gt;Am I saying that you should never use unit tests in a new language? Of course not. However, you should chose the right level of test to match your level of understanding. Once your application&amp;#8217;s structure has ossified it makes sense to exercise the complex parts directly through unit tests. The second you make that shift to using using tests you are setting your structure in stone so you want to make sure that does not happen before it has to.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=b8CXNYC7YWI:Q8aiJKOvs0g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=b8CXNYC7YWI:Q8aiJKOvs0g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=b8CXNYC7YWI:Q8aiJKOvs0g:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=b8CXNYC7YWI:Q8aiJKOvs0g:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=b8CXNYC7YWI:Q8aiJKOvs0g:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=b8CXNYC7YWI:Q8aiJKOvs0g:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=b8CXNYC7YWI:Q8aiJKOvs0g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/b8CXNYC7YWI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/b8CXNYC7YWI/1617097196</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/1617097196</guid><pubDate>Fri, 19 Nov 2010 08:04:06 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/1617097196</feedburner:origLink></item><item><title>Simple tools and fundamental principles</title><description>&lt;p&gt;We are doing an experiment in using Ruby for an internal project &lt;a title="Adgistics" href="http://www.adgistics.com/"&gt;at work&lt;/a&gt;. I am the most experienced in Ruby so I&amp;#8217;m leading the choices of gems and so forth and the team questioning those choices has lead to a bit of a personal epiphany.&lt;/p&gt;
&lt;p&gt;I know that for a long while I have preferred simple tools and components. Simple tools tend to be more enabling as they give you control over precisely what is happening in your application whilst managing the boilerplate code for you. I&amp;#8217;ve also focused my personal development and reading on fundamental principles to give me a solid grounding in concepts that can then be applied to any situation or language.&lt;/p&gt;
&lt;p&gt;These opinions are being reflected in the tools I use for my Ruby development and therefore what I am encouraging the other developers at my company to use: &lt;a title="Sinatra" href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; and &lt;a title="Sequel" href="http://sequel.rubyforge.org/"&gt;Sequel&lt;/a&gt;. I enjoy the power you get from both to exploit all that is available from HTTP and SQL. I find it much easier to apply my knowledge of HTTP gained through reading about REST, though I doubt I&amp;#8217;ll ever write a truly RESTful application. Things such as returning the correct HTTP codes and headers to enable client and proxy caching are ridiculously easy to do when compared to ASP.NET MVC. Being able to leverage my knowledge of SQL allows me to fine tune that vital query yet Sequel will still give me back easily consumable objects.&lt;/p&gt;
&lt;p&gt;Choosing these simple tools for our task will help the team to learn Ruby and build an application, the real point of the task, rather than spending a large period of time learning how to use a more powerful framework such as Rails. The simpler tools should also let them exercise more of their existing knowledge, again allowing them to focus on learning the Ruby language rather than being distracted by Ruby frameworks.&lt;/p&gt;
&lt;p&gt;As for me, I&amp;#8217;m happy I&amp;#8217;ve chosen this method of working and learning. I think it will stand me in good stead for working in any language I may want or need to learn in the future. It will be interesting to hear what the team thinks of this approach as we proceed.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5sg7W3RJb6s:HUkYr7cW7wY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=5sg7W3RJb6s:HUkYr7cW7wY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5sg7W3RJb6s:HUkYr7cW7wY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5sg7W3RJb6s:HUkYr7cW7wY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=5sg7W3RJb6s:HUkYr7cW7wY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5sg7W3RJb6s:HUkYr7cW7wY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=5sg7W3RJb6s:HUkYr7cW7wY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/5sg7W3RJb6s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/5sg7W3RJb6s/1609359955</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/1609359955</guid><pubDate>Thu, 18 Nov 2010 13:00:49 +0000</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/1609359955</feedburner:origLink></item><item><title>The Long Beard's Revenge</title><description>&lt;a href="http://sheddingbikes.com/posts/1286998492.html"&gt;The Long Beard's Revenge&lt;/a&gt;: &lt;p&gt;Very interesting article on a reduction in contribution to open source and the possibly underlying forces behind it.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fgGJhH-s69w:hi7iVviZ3qY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=fgGJhH-s69w:hi7iVviZ3qY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fgGJhH-s69w:hi7iVviZ3qY:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fgGJhH-s69w:hi7iVviZ3qY:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=fgGJhH-s69w:hi7iVviZ3qY:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fgGJhH-s69w:hi7iVviZ3qY:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=fgGJhH-s69w:hi7iVviZ3qY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/fgGJhH-s69w" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/fgGJhH-s69w/1312099757</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/1312099757</guid><pubDate>Thu, 14 Oct 2010 10:15:00 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/1312099757</feedburner:origLink></item><item><title>10 Common Mistakes Made by API Providers</title><description>&lt;a href="http://www.readwriteweb.com/cloud/2010/08/the-new-api-movement-may.php"&gt;10 Common Mistakes Made by API Providers&lt;/a&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=jFX7N5AvYns:cAAinlNH1xg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=jFX7N5AvYns:cAAinlNH1xg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=jFX7N5AvYns:cAAinlNH1xg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=jFX7N5AvYns:cAAinlNH1xg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?i=jFX7N5AvYns:cAAinlNH1xg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=jFX7N5AvYns:cAAinlNH1xg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/RobustSoftware?a=jFX7N5AvYns:cAAinlNH1xg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/RobustSoftware?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/RobustSoftware/~4/jFX7N5AvYns" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/RobustSoftware/~3/jFX7N5AvYns/1290123273</link><guid isPermaLink="false">http://www.robustsoftware.co.uk/post/1290123273</guid><pubDate>Mon, 11 Oct 2010 09:39:54 +0100</pubDate><feedburner:origLink>http://www.robustsoftware.co.uk/post/1290123273</feedburner:origLink></item></channel></rss>

