<?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>CodeBetter.Com</title>
	
	<link>http://codebetter.com</link>
	<description>Stuff you need to Code Better!</description>
	<lastBuildDate>Sat, 10 Dec 2011 20:21:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
	
	
	       
    	<feedburner:info uri="codebetter" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/MatthewPodwysocki" /><feedburner:info uri="matthewpodwysocki" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Code Query and Rule over LINQ</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/21tRUJanTG0/</link>
		<comments>http://codebetter.com/patricksmacchia/2012/05/24/code-query-and-rule-over-linq/#comments</comments>
		<pubDate>Thu, 24 May 2012 16:52:42 +0000</pubDate>
		<dc:creator>Patrick Smacchia</dc:creator>
				<category><![CDATA[Code Query]]></category>
		<category><![CDATA[Code Rule]]></category>
		<category><![CDATA[CQLinq]]></category>
		<category><![CDATA[NDepend]]></category>
		<category><![CDATA[Object oriented programming]]></category>
		<category><![CDATA[VS Integration]]></category>
			<guid isPermaLink="false">http://codebetter.com/patricksmacchia/?p=525</guid>
					<description><![CDATA[Yesterday, after two years of a relentless development effort, we finally released NDepend v4. Personally, I consider this version as the biggest milestone we&#8217;ve ever achieved. The three flagship features are: Code query and rule over LINQ (CQLinq) NDepend.API to&#160;&#8230; <a href="http://codebetter.com/patricksmacchia/2012/05/24/code-query-and-rule-over-linq/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Yesterday, after two years of a relentless development effort, we finally released NDepend v4. Personally, I consider this version as the biggest milestone we&#8217;ve ever achieved. The three flagship features are:</p>
<ul>
<li>Code query and rule over LINQ (<strong>CQLinq</strong>)</li>
<li><strong>NDepend.API</strong> to let user develop its own static analyzers (+14 OSS Power Tools proposed on top of NDepend.API)</li>
<li>VS11 addin support</li>
</ul>
<p>Developing these features by respecting the following drastic requirements was a real challenge:</p>
<ul>
<li><strong><a href="http://www.ndepend.com/Doc_CQLinq_Features.aspx" target="_blank">Features Richness</a></strong>: The code query features set was already rich in prior versions, but we wanted it to be even richer to be able to write easily all the code queries and rules that existing users asked us.</li>
<li><strong><a href="http://www.ndepend.com/Doc_CQLinq_Syntax.aspx" target="_blank">Syntax</a></strong>: Queries must be easy to write and to read. Hopefully most NDepend users are aware of the C# LINQ syntax, but the proposed code model API needs to be LINQ-friendly. We started with a three months research effort to define what was the cleanest syntax to express a few dozens of <em>essential</em> code queries. A few natural syntax enhancements were also developed (like the prefix <strong>warnif count &gt; 0</strong> to transform a code query into a code rule).</li>
<li><strong><a href="http://www.ndepend.com/Doc_CQLinq_Perf.aspx" target="_blank">Performance</a></strong>: We wanted something like a hundred of queries compiled and executed per second against a large real-world code base, because we want them to be run often in VS without slowing down the IDE.</li>
<li><strong>Usability</strong>: We wanted query edition to be seamless thanks to code completion, live tooltip documentation and detailed error reporting.  All this without the <a href="http://codebetter.com/patricksmacchia/2011/10/20/roslyn-ctp-is-available/" target="_blank">Roslyn</a> power that is not yet RTM. Also, for v3 users, we&#8217;ve developed a CQL to CQLinq automatic converter (and CQL is still supported).</li>
</ul>
<p>One simple CQLinq code rule that illustrates well all these, is the following one.</p>
<script src="http://gist.github.com/2781941.js"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-2781941" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c1">// &lt;Name&gt;Base class should not use derivatives&lt;/Name&gt;</span></div><div class='line' id='LC2'><span class="n">warnif</span> <span class="n">count</span> <span class="p">&gt;</span> <span class="m">0</span> </div><div class='line' id='LC3'><span class="k">from</span> <span class="n">baseClass</span> <span class="k">in</span> <span class="n">JustMyCode</span><span class="p">.</span><span class="n">Types</span></div><div class='line' id='LC4'><span class="k">where</span> <span class="n">baseClass</span><span class="p">.</span><span class="n">IsClass</span> <span class="p">&amp;&amp;</span> <span class="n">baseClass</span><span class="p">.</span><span class="n">NbChildren</span> <span class="p">&gt;</span> <span class="m">0</span> <span class="c1">// &lt;-- for optimization!</span></div><div class='line' id='LC5'><span class="n">let</span> <span class="n">derivedClassesUsed</span> <span class="p">=</span> <span class="n">baseClass</span><span class="p">.</span><span class="n">DerivedTypes</span><span class="p">.</span><span class="n">UsedBy</span><span class="p">(</span><span class="n">baseClass</span><span class="p">)</span></div><div class='line' id='LC6'><span class="k">where</span> <span class="n">derivedClassesUsed</span><span class="p">.</span><span class="n">Count</span><span class="p">()</span> <span class="p">&gt;</span> <span class="m">0</span></div><div class='line' id='LC7'><span class="k">select</span> <span class="k">new</span> <span class="p">{</span> <span class="n">baseClass</span><span class="p">,</span> <span class="n">derivedClassesUsed</span> <span class="p">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2781941/fa8d3e10cfed53b924e5b04fe70b6d56f277c4b1/gistfile1.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2781941#file_gistfile1.cs" style="float:right;margin-right:10px;color:#666">gistfile1.cs</a>
            <a href="https://gist.github.com/2781941">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript>
<p>Hopefully the syntax is simple enough to convey the underlying meaning to any .NET developer. Only the <a href="http://www.ndepend.com/Doc_CQLinq_Syntax.aspx#NotMyCode" target="_blank">JustMyCode</a> highlighted word might not be clear. It represents a facility proposed to avoid matching generated code elements, that often are pesky false positive matches for code rules.</p>
<p>After  an instantaneous compilation/execution phase (1 millisecond), the result is displayed with facilities for browsing it and exporting it:</p>
<p><a href="http://codebetter.com/patricksmacchia/files/2012/05/CQLinq_Overview1.png"><img class="alignnone size-full wp-image-542" src="http://codebetter.com/patricksmacchia/files/2012/05/CQLinq_Overview1.png" alt="" width="445" height="717" /></a></p>
<p>Today, I&#8217;d like to focus a bit more on the syntax aspect. Developing for LINQ and with LINQ during the last two years has been a great joy. Everybody agrees that LINQ is <em>very</em> elegant, but it is also a super-extensible technology.</p>
<p>We extended LINQ in several different ways. One way has been to develop a LINQ-friendly <a href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank">fluent API</a>. Often we found convenient to write default code rules with a mix of both <a href="http://www.ndepend.com/Doc_CQLinq_Syntax.aspx#OperatorsExpressions" target="_blank">Query Expression and Query Operator</a> syntaxes. Takes the following rule for example.</p>
<script src="http://gist.github.com/2781949.js"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-2781949" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>// &lt;Name&gt;UI layer shouldn&#39;t use directly DB types&lt;/Name&gt;</div><div class='line' id='LC2'>warnif count &gt; 0</div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>// UI layer is made of types in namespaces using a UI framework</div><div class='line' id='LC5'>let uiTypes = Application.Namespaces.UsingAny(</div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;Assemblies.WithNameIn(&quot;PresentationFramework&quot;, &quot;System.Windows&quot;, </div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;System.Windows.Forms&quot;, &quot;System.Web&quot;)</div><div class='line' id='LC8'>).ChildTypes()</div><div class='line' id='LC9'><br/></div><div class='line' id='LC10'>// You can easily customize this line to define what are DB types.</div><div class='line' id='LC11'>let dbTypes = ThirdParty.Assemblies.WithNameIn(&quot;System.Data&quot;, &quot;EntityFramework&quot;, </div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;NHibernate&quot;).ChildTypes()</div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Ideally even DataSet and associated, usage should be forbidden from UI layer: </div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// http://stackoverflow.com/questions/1708690/is-list-better-than-dataset-for-ui-layer-in-asp-net</div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Except(Types.WithNameIn(&quot;DataSet&quot;, &quot;DataTable&quot;, &quot;DataRow&quot;))</div><div class='line' id='LC16'><br/></div><div class='line' id='LC17'>from uiType in uiTypes.UsingAny(dbTypes)</div><div class='line' id='LC18'>let dbTypesUsed = dbTypes.Intersect(uiType.TypesUsed)</div><div class='line' id='LC19'>select new { uiType, dbTypesUsed }</div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2781949/9eba86accad5cd4b914b104e57c63e36bbb8b38a/gistfile1.txt" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2781949#file_gistfile1.txt" style="float:right;margin-right:10px;color:#666">gistfile1.txt</a>
            <a href="https://gist.github.com/2781949">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript>
<ul>
<li>First, we define with two fluent sub-queries (<em>expressed with the operator syntax</em>)  the UI layer (<em>types in namespaces using any UI framework</em>) and the DB layer (<em>types in namespaces using any DB framework</em>)</li>
<li>Then we use more fluent query operator syntax to check if the UI layer is using the DB layer.</li>
<li>Finally the whole query is structured with the query expression syntax.</li>
</ul>
<p>In a few lines of code, we are expressing fluently a pretty complex and popular requirement, in a generic way adaptable to any situations.</p>
<p>For a few years now, the code metric C.R.A.P (Change Risk Analyzer and Predictor) became increasingly popular in the Java community thanks to the <a href="http://www.crap4j.org/" target="_blank">crap4J plugin</a>. The C.R.A.P metric has been exposed by <em>Alberto Savoia</em> in this <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=215899" target="_blank">Artima article</a> dated from October 2007. The C.R.A.P metric is a mathematical formula that helps to determine which piece of code is <em>both</em> complex and poorly covered by tests. Since both <em>code coverage</em> and <em>cyclomatic complexity</em> code metrics are proposed by the NDepend.API code model, it is fairly easy to write a CQLinq code rule to match <em>crappy </em>code:</p>
<script src="http://gist.github.com/2781932.js"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-2781932" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c1">// &lt;Name&gt;C.R.A.P method code metric&lt;/Name&gt;</span></div><div class='line' id='LC2'><span class="c1">// Change Risk Analyzer and Predictor (i.e. CRAP) code metric</span></div><div class='line' id='LC3'><span class="c1">// This code metric helps in pinpointing overly complex and untested code.</span></div><div class='line' id='LC4'><span class="c1">// Reference: http://www.artima.com/weblogs/viewpost.jsp?thread=215899</span></div><div class='line' id='LC5'><span class="c1">// Formula:   CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)</span></div><div class='line' id='LC6'><span class="n">warnif</span> <span class="n">count</span> <span class="p">&gt;</span> <span class="m">0</span></div><div class='line' id='LC7'><span class="k">from</span> <span class="n">m</span> <span class="k">in</span> <span class="n">JustMyCode</span><span class="p">.</span><span class="n">Methods</span></div><div class='line' id='LC8'><br/></div><div class='line' id='LC9'><span class="c1">// Don&#39;t match too short methods</span></div><div class='line' id='LC10'><span class="k">where</span> <span class="n">m</span><span class="p">.</span><span class="n">NbLinesOfCode</span> <span class="p">&gt;</span> <span class="m">10</span></div><div class='line' id='LC11'><br/></div><div class='line' id='LC12'><span class="n">let</span> <span class="n">CC</span> <span class="p">=</span> <span class="n">m</span><span class="p">.</span><span class="n">CyclomaticComplexity</span></div><div class='line' id='LC13'><span class="n">let</span> <span class="n">uncov</span> <span class="p">=</span> <span class="p">(</span><span class="m">100</span> <span class="p">-</span> <span class="n">m</span><span class="p">.</span><span class="n">PercentageCoverage</span><span class="p">)</span> <span class="p">/</span> <span class="m">100f</span></div><div class='line' id='LC14'><span class="n">let</span> <span class="n">CRAP</span> <span class="p">=</span> <span class="p">(</span><span class="n">CC</span> <span class="p">*</span> <span class="n">CC</span> <span class="p">*</span> <span class="n">uncov</span> <span class="p">*</span> <span class="n">uncov</span> <span class="p">*</span> <span class="n">uncov</span><span class="p">)</span> <span class="p">+</span> <span class="n">CC</span></div><div class='line' id='LC15'><span class="k">where</span> <span class="n">CRAP</span> <span class="p">!=</span> <span class="k">null</span> <span class="p">&amp;&amp;</span> <span class="n">CRAP</span> <span class="p">&gt;</span> <span class="m">30</span></div><div class='line' id='LC16'><span class="k">orderby</span> <span class="n">CRAP</span> <span class="k">descending</span><span class="p">,</span> <span class="n">m</span><span class="p">.</span><span class="n">NbLinesOfCode</span> <span class="k">descending</span></div><div class='line' id='LC17'><span class="k">select</span> <span class="k">new</span> <span class="p">{</span> <span class="n">m</span><span class="p">,</span> <span class="n">CRAP</span><span class="p">,</span> <span class="n">CC</span><span class="p">,</span> <span class="n">uncoveredPercentage</span> <span class="p">=</span> <span class="n">uncov</span><span class="p">*</span><span class="m">100</span><span class="p">,</span> <span class="n">m</span><span class="p">.</span><span class="n">NbLinesOfCode</span> <span class="p">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2781932/7ca26f81ffbb9507eead9d06ca3271943feb923d/gistfile1.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2781932#file_gistfile1.cs" style="float:right;margin-right:10px;color:#666">gistfile1.cs</a>
            <a href="https://gist.github.com/2781932">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript>
<p>A popular feature of NDepend is the ability to diff two snapshots of a code base to explore what was changed. This feature being completely integrated with CQLinq, it is now possible to write <em>simple</em> code queries that will match <em>complex</em> evolution requirements. One immediate requirement that comes to my mind, is that a class 100% covered by tests should remain 100% covered by tests, no matter whether it has been touched or not. The following CQLinq code rule detects classes that are not anymore 100% covered by tests (since the predefined <em>base-line</em>), and lists the <em>culprit</em> methods, i.e the method that are not 100% covered anymore:</p>
<script src="http://gist.github.com/2781961.js"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-2781961" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c1">// &lt;Name&gt;Types that used to be 100% covered but not anymore&lt;/Name&gt;</span></div><div class='line' id='LC2'><span class="n">warnif</span> <span class="n">count</span> <span class="p">&gt;</span> <span class="m">0</span></div><div class='line' id='LC3'><span class="k">from</span> <span class="n">t</span> <span class="k">in</span> <span class="n">JustMyCode</span><span class="p">.</span><span class="n">Types</span> <span class="k">where</span> </div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;<span class="n">t</span><span class="p">.</span><span class="n">IsPresentInBothBuilds</span><span class="p">()</span> <span class="p">&amp;&amp;</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;<span class="n">t</span><span class="p">.</span><span class="n">OlderVersion</span><span class="p">().</span><span class="n">PercentageCoverage</span> <span class="p">==</span> <span class="m">100</span> <span class="p">&amp;&amp;</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;<span class="n">t</span><span class="p">.</span><span class="n">PercentageCoverage</span> <span class="p">&lt;</span> <span class="m">100</span></div><div class='line' id='LC7'><span class="n">let</span> <span class="n">culpritMethods</span> <span class="p">=</span> <span class="n">t</span><span class="p">.</span><span class="n">Methods</span><span class="p">.</span><span class="n">Where</span><span class="p">(</span><span class="n">m</span> <span class="p">=&gt;</span> <span class="n">m</span><span class="p">.</span><span class="n">PercentageCoverage</span> <span class="p">&lt;</span> <span class="m">100</span><span class="p">)</span></div><div class='line' id='LC8'><span class="k">select</span> <span class="k">new</span> <span class="p">{</span><span class="n">t</span><span class="p">,</span> <span class="n">t</span><span class="p">.</span><span class="n">PercentageCoverage</span><span class="p">,</span> <span class="n">culpritMethods</span> <span class="p">}</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2781961/8f9a700ab6dddfd1083d21db38f7d082233de869/gistfile1.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2781961#file_gistfile1.cs" style="float:right;margin-right:10px;color:#666">gistfile1.cs</a>
            <a href="https://gist.github.com/2781961">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript>
<p>Hopefully CQLinq is a simple answer to many requirements that formerly demanded significant efforts (imagine the effort to develop the tool crap4J compared to the effort of writing a single CQLinq query). You can <a href="http://www.ndepend.com/NDependV4.aspx" target="_blank">download freely and try</a> CQLinq live on your code base, and here you can browse all <a href="http://www.ndepend.com/DefaultRules/webframe.html" target="_blank">200 default code rules</a>.</p>
<p>In future posts I&#8217;ll dig into the low-level implementation tricks needed to implement all this.</p>
<div class="shr-publisher-525"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fpatricksmacchia%2F2012%2F05%2F24%2Fcode-query-and-rule-over-linq%2F' data-shr_title='Code+Query+and+Rule+over+LINQ'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fpatricksmacchia%2F2012%2F05%2F24%2Fcode-query-and-rule-over-linq%2F' data-shr_title='Code+Query+and+Rule+over+LINQ'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fpatricksmacchia%2F2012%2F05%2F24%2Fcode-query-and-rule-over-linq%2F' data-shr_title='Code+Query+and+Rule+over+LINQ'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/dvzVZzloigs" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/21tRUJanTG0" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/patricksmacchia/2012/05/24/code-query-and-rule-over-linq/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
					<feedburner:origLink>http://codebetter.com/patricksmacchia/2012/05/24/code-query-and-rule-over-linq/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/dvzVZzloigs/</feedburner:origLink></item>
	      
    	<item>
		<title>Two ways to work with HTTP responses in ApiController, HttpResponseMessage and HttpResponseException</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/UlYByCnpjCU/</link>
		<comments>http://codebetter.com/glennblock/2012/05/24/two-ways-to-work-with-http-responses-in-apicontroller-httpresponsemessage-and-httpresponseexception/#comments</comments>
		<pubDate>Thu, 24 May 2012 09:29:51 +0000</pubDate>
		<dc:creator>Glenn Block</dc:creator>
				<category><![CDATA[ASP.NET Web API]]></category>
			<guid isPermaLink="false">http://codebetter.com/glennblock/?p=420</guid>
					<description><![CDATA[ASP.NET Web API provides two different ways to work with manipulating HTTP response messages from within your API Controller action. Throw an HttpResonseException – This exception allows you to pass in an HttpResponseMessage / set status and headers. Web API&#160;&#8230; <a href="http://codebetter.com/glennblock/2012/05/24/two-ways-to-work-with-http-responses-in-apicontroller-httpresponsemessage-and-httpresponseexception/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>ASP.NET Web API provides two different ways to work with manipulating HTTP response messages from within your API Controller action. </p>
<ul>
<li>Throw an HttpResonseException – This exception allows you to pass in an HttpResponseMessage / set status and headers. Web API will then immediately return the response.
<li>Return an HttpResponseMessage – You can simply return an HttpResponseMessage from your action.</li>
</ul>
<p>So which&nbsp; should you use when? Are they both identical? Cuong Le recently <a href="http://stackoverflow.com/questions/10660721/asp-net-web-api-different-between-httpresponsemessage-and-httpresponseexception">asked</a> this question on StackOverflow.</p>
<p>The simple answer is no they are not the same.</p>
<p>The main difference between the two is this. The exception is useful to immediately stop processing and exit. For example assume I have the following code</p>
<script src="http://gist.github.com/2780444.js"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-2780444" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="k">class</span> <span class="nc">CustomerController</span> <span class="p">:</span> <span class="n">ApiController</span> <span class="p">{</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">private</span> <span class="n">ICustomerContext</span> <span class="n">repo</span><span class="p">;</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="nf">CustomerController</span><span class="p">(</span><span class="n">ICustomerContext</span> <span class="n">repo</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">.</span><span class="n">repo</span> <span class="p">=</span> <span class="n">repo</span><span class="p">;</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="n">Customer</span> <span class="nf">Get</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kt">var</span> <span class="n">customer</span> <span class="p">=</span> <span class="n">repo</span><span class="p">.</span><span class="n">Customers</span><span class="p">.</span><span class="n">SingleOrDefault</span><span class="p">(</span><span class="n">c</span><span class="p">=&gt;</span><span class="n">c</span><span class="p">.</span><span class="n">CustomerID</span> <span class="p">==</span> <span class="n">id</span><span class="p">);</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">if</span> <span class="p">(</span><span class="n">customer</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">throw</span> <span class="k">new</span> <span class="nf">HttpResponseException</span><span class="p">(</span><span class="k">new</span> <span class="n">HttpResponseMessage</span><span class="p">(</span><span class="n">HttpStatusCode</span><span class="p">.</span><span class="n">NotFound</span><span class="p">));</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">customer</span><span class="p">;</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC16'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2780444/dc824790b96d7f3544ea7b13abc48832b885ed76/gistfile1.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2780444#file_gistfile1.cs" style="float:right;margin-right:10px;color:#666">gistfile1.cs</a>
            <a href="https://gist.github.com/2780444">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript>
<p>If this code runs and I pass an id that is not present, it will immediately stop processing and return a status code of 404.</p>
<p>If instead I return HttpResponseMessage, the request will happily continue the rest of it&#8217;s processing and return a 404. The main difference being end the request or not.</p>
<p>As <a href="http://twitter.com/darrel_miller">Darrel</a> said, the exception is useful in cases where in some cases I want processing to continue (as in when customer is found) and in others I don&#8217;t.</p>
<p>The place where you might want to return HttpResponseMessage directly is in an HTTP POST to return a status code of 201 and set the location header. In that case I do want processing to continue. That would would do with this code.*</p>
<script src="http://gist.github.com/2780448.js"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-2780448" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="k">class</span> <span class="nc">CustomerController</span> <span class="p">:</span> <span class="n">ApiController</span> <span class="p">{</span></div><div class='line' id='LC2'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">private</span> <span class="n">ICustomerContext</span> <span class="n">repo</span><span class="p">;</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="nf">CustomerController</span><span class="p">(</span><span class="n">ICustomerContext</span> <span class="n">repo</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC5'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">this</span><span class="p">.</span><span class="n">repo</span> <span class="p">=</span> <span class="n">repo</span><span class="p">;</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC7'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div><div class='line' id='LC8'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">public</span> <span class="n">HttpResponseMessage</span> <span class="nf">Post</span><span class="p">(</span><span class="n">Customer</span> <span class="n">customer</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC9'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">repo</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">customer</span><span class="p">);</span></div><div class='line' id='LC10'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">repo</span><span class="p">.</span><span class="n">SaveChanges</span><span class="p">();</span></div><div class='line' id='LC11'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="kt">var</span> <span class="n">response</span> <span class="p">=</span> <span class="n">Request</span><span class="p">.</span><span class="n">CreateResponse</span><span class="p">(</span><span class="n">HttpStatusCode</span><span class="p">.</span><span class="n">Created</span><span class="p">,</span> <span class="n">customer</span><span class="p">);</span></div><div class='line' id='LC12'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">response</span><span class="p">.</span><span class="n">Headers</span><span class="p">.</span><span class="n">Location</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Uri</span><span class="p">(</span><span class="n">Request</span><span class="p">.</span><span class="n">RequestUri</span><span class="p">,</span> <span class="kt">string</span><span class="p">.</span><span class="n">format</span><span class="p">(</span><span class="s">&quot;customer/{0}&quot;</span><span class="p">,</span> <span class="n">customer</span><span class="p">.</span><span class="n">id</span><span class="p">));</span></div><div class='line' id='LC13'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="k">return</span> <span class="n">response</span><span class="p">;</span></div><div class='line' id='LC14'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC15'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="p">}</span></div><div class='line' id='LC16'><br/></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2780448/eb30ccf61fcb1a55c8dbea5131dfa8282761ebb3/gistfile1.cs" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2780448#file_gistfile1.cs" style="float:right;margin-right:10px;color:#666">gistfile1.cs</a>
            <a href="https://gist.github.com/2780448">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript>
<p><strong>*note:</strong> If you are using the beta bits you would create a new HttpResponseMessage&lt;Customer&gt;. I am using the later bits however which require you to use the CreateResponse extension method off of the Request.</p>
<p>Above, I am creating a response which sets the status code to 201, passes in the customer, and then sets the location header.</p>
<p>The response is then returned and the request continues processing.</p>
<p>Hope this helps clarify the difference.</p>
<div class="shr-publisher-420"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F24%2Ftwo-ways-to-work-with-http-responses-in-apicontroller-httpresponsemessage-and-httpresponseexception%2F' data-shr_title='Two+ways+to+work+with+HTTP+responses+in+ApiController%2C+HttpResponseMessage+and+HttpResponseException'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F24%2Ftwo-ways-to-work-with-http-responses-in-apicontroller-httpresponsemessage-and-httpresponseexception%2F' data-shr_title='Two+ways+to+work+with+HTTP+responses+in+ApiController%2C+HttpResponseMessage+and+HttpResponseException'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F24%2Ftwo-ways-to-work-with-http-responses-in-apicontroller-httpresponsemessage-and-httpresponseexception%2F' data-shr_title='Two+ways+to+work+with+HTTP+responses+in+ApiController%2C+HttpResponseMessage+and+HttpResponseException'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/4YRghb28wnE" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/UlYByCnpjCU" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/glennblock/2012/05/24/two-ways-to-work-with-http-responses-in-apicontroller-httpresponsemessage-and-httpresponseexception/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
					<feedburner:origLink>http://codebetter.com/glennblock/2012/05/24/two-ways-to-work-with-http-responses-in-apicontroller-httpresponsemessage-and-httpresponseexception/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/4YRghb28wnE/</feedburner:origLink></item>
	      
    	<item>
		<title>A story on composable systems</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/GIffuWpzjbI/</link>
		<comments>http://codebetter.com/drusellers/2012/05/23/a-story-on-composable-systems/#comments</comments>
		<pubDate>Wed, 23 May 2012 14:37:41 +0000</pubDate>
		<dc:creator>Dru Sellers</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
			<guid isPermaLink="false">http://codebetter.com/drusellers/?p=285</guid>
					<description><![CDATA[&#60;warning&#62;This is a long post that attempts to describe a positive experience leveraging multiple frameworks&#60;/warning&#62; TL;DR. Static Typing / IoC == AWESOME FLEXIBILITY Recently while working at Dovetail I had the absolute pleasure to provide a solution to a customer&#160;&#8230; <a href="http://codebetter.com/drusellers/2012/05/23/a-story-on-composable-systems/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>&lt;warning&gt;This is a long post that attempts to describe a positive experience leveraging multiple frameworks&lt;/warning&gt;</p>
<p>TL;DR. Static Typing / IoC == AWESOME FLEXIBILITY</p>
<p>Recently while working at Dovetail I had the absolute pleasure to provide a solution to a customer request. We were adding SAML authentication to our product, and we wanted to provide an extensibility point to handle unknown users. By default the product would show a not authorized screen if we encountered a valid SAML assertion referencing an unknown user. This was pretty easy to setup, but as I said, we really wanted this to be extensible. What I wanted to support was redirecting the user to a different page, maybe one that a customer has specified which would give the user the information needed to request access to our application through the approved channels. That would have been pretty easy with just a configuration entry, but we decided that really wasn&#8217;t enough. We also wanted to be able to handle a request to make a user right there. Well, now we need the ability to execute some code, a configuration file isn&#8217;t going to handle that very well. Even if we kept the config file approach we would have to redirect the user to somewhere else in the app, and then figure out how to shuffle all of the required data around. <img src='http://codebetter.com/drusellers/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />  It just didn’t feel like a solid solution.</p>
<p>Thankfully, FubuMVC, Bottles and StructureMap came to the rescue. FubuMVC gives us controllers that can easily take dependencies on services (nothing to fancy here, you can do this in ASP.NET MVC too). So our SAML Authentication controller (or action in Fubu land) takes in a service that acts as a policy (SuccessfulSamlAssertionPolicy) it takes a valid SAML assertion, and attempts to locate the user in the database, if it finds them, the policy logs them in, and then redirects the user to the home page. If we can&#8217;t find the user, then we invoke the UnknownUserPolicy (another service/policy thing which is injected in the SuccessfulSamlAssetionPolicy) the default implementation of this policy simply redirects them to an error page of ours, but since it&#8217;s a interface/class pair, we can easily swap that out. This is where IoC/DI/StructureMap make things really nice.</p>
<p>So, the above may seem a bit complex (I definitely didn&#8217;t explain it that well). So lets break it down and make it concrete. I have an interface that looks like this</p>
<pre class="brush: csharp; title: ; notranslate">
public interface UnknownUserPolicy
{
    //FubuContinuation is a way to redirect the user
    FubuContinuation HandleUnknownUser(SamlAssertion assertion);
}
</pre>
<p>we ship with the following implementation</p>
<pre class="brush: csharp; title: ; notranslate">
public class DefaultUnknownUserPolicy : UnknownUserPolicy
{
    public FubuContinuation HandleUnknownUser(SamlAssertion assertion)
    {
        return FubuContinuation.RedirectTo&lt;LoginController&gt;(c =&gt; c.Login(null));
    }
}
</pre>
<p>Super easy code, nothing too hard here. We wire it up in StructureMap using a convention, so there is really nothing else to show. Now, lets imagine we have a customer, that doesn&#8217;t want them redirected to the login page, they should instead go to: <a href="https://silly.corporate.subdomain.company.com/request_access.cfm">https://silly.corporate.subdomain.company.com/request_access.cfm</a> . Using StructureMap, this is as easy as registering our policy later in the container (after the default registrations) by adding a line like this:</p>
<pre class="brush: csharp; title: ; notranslate">
For&lt;UnknownUserPolicy&gt;().Use&lt;CompanyXUnknownUserPolicy&gt;();
</pre>
<p>That will override the default policy and boom! We have just customized our application for this one customer. So that&#8217;s great and all &#8211; but I want that in only ONE deployed instance of the application. I do not want to modify the base product for this customer, and this is where Bottles comes to my rescue. <img src='http://codebetter.com/drusellers/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Bottles is a framework for assisting us in loading dynamic code in a controlled and predictable manner. Its built with an IoC container in mind, but is completely agnostic of them and FubuMVC entirely. When our application starts up, we go through all the usual stuff for a .Net / IoC project. We initialize logging, spin up our container, blah, blah, blah. The one new step that we add with Bottles though, is to run through every discovered Bottle, and look for &#8216;StructureMap Registries&#8217; and load them into the container. Now, a bottle is pretty much a glorified zip file holding .Net assemblies &#8212; among other things. The bottles, being a separate file from the base product, can be used to modify our existing application. In this case, we have a Customer Bottle that does one thing. It executes that above piece of SM registration code to override the base UnknownUserPolicy. <img src='http://codebetter.com/drusellers/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  WIN.</p>
<p>So, by putting all of these various tools, patterns, and frameworks together, we were able to build a solution that allows for a lot of customizability, does NOT require us to change our base product (would have loved to have had this at the bank), and I think truly encapsulates the changes that customizations for a customer can bring into one easily deployable unit.</p>
<p>There are a LOT of things going on in this post, we have programming to interfaces, we have making small classes that do one thing well, we are using IoC, we are using a web framework that makes redirecting deep in the bowels of the app easy and testable, we have composition, dynamic code loading and a lot of &#8216;abstractions&#8217; (Yup, learned about those at a young age <img src='http://codebetter.com/drusellers/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ). Using all of these has allowed us to add a lot of seams to our application, and it’s this kind of power that keeps our application nimble and easily customizable for any customer.</p>
<div class="shr-publisher-285"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F05%2F23%2Fa-story-on-composable-systems%2F' data-shr_title='A+story+on+composable+systems'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F05%2F23%2Fa-story-on-composable-systems%2F' data-shr_title='A+story+on+composable+systems'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F05%2F23%2Fa-story-on-composable-systems%2F' data-shr_title='A+story+on+composable+systems'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/aYR_xw67lFo" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/GIffuWpzjbI" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/drusellers/2012/05/23/a-story-on-composable-systems/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
					<feedburner:origLink>http://codebetter.com/drusellers/2012/05/23/a-story-on-composable-systems/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/aYR_xw67lFo/</feedburner:origLink></item>
	      
    	<item>
		<title>A Gentle Reintroduction to the Reactive Extensions for JavaScript</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/h22d8dbLR0s/</link>
		<comments>http://codebetter.com/matthewpodwysocki/2012/05/21/a-gentle-reintroduction-to-the-reactive-extensions-for-javascript/#comments</comments>
		<pubDate>Mon, 21 May 2012 15:37:00 +0000</pubDate>
		<dc:creator>Matthew Podwysocki</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Reactive Framework]]></category>
		<category><![CDATA[RxJS]]></category>
		<category><![CDATA[RxNET]]></category>
			<guid isPermaLink="false">http://codebetter.com/matthewpodwysocki/?p=261</guid>
					<description><![CDATA[One of the things that I’ve been doing since I last blogged has been working on the Reactive Extensions for JavaScript (RxJS).&#160; Since I last blogged, we have had two releases, a version 1.0.10621 SP1 which we released back in&#160;&#8230; <a href="http://codebetter.com/matthewpodwysocki/2012/05/21/a-gentle-reintroduction-to-the-reactive-extensions-for-javascript/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>One of the things that I’ve been doing since I last blogged has been working on the <a href="http://msdn.microsoft.com/en-us/data/gg577612">Reactive Extensions for JavaScript (RxJS)</a>.&nbsp; Since I last blogged, we have had two releases, a version 1.0.10621 SP1 which we released back in December of last year and version 2.0 Beta which was just released a couple of weeks ago.&nbsp; You can check out the release notes for each version, <a href="http://social.msdn.microsoft.com/Forums/en-US/rx/thread/b4c6511d-132d-430e-9a5c-b345465bad83">v1.0.10621 SP1</a> and <a href="http://social.msdn.microsoft.com/Forums/en-US/rx/thread/f95ce2b7-8669-44af-8baf-4ab3c069a5eb">v2.0.20327 Beta</a> respectively.&nbsp; Along with these releases, we’ve also put the packages up on <a href="https://nuget.org/packages?q=RxJS">NuGet</a>, create Visual Studio style documentation/intellisense, and put the bindings for third-party libraries and runtimes such as Node.js, jQuery, Dojo, ExtJS, MooTools and others on <a href="https://github.com/reactive-extensions">GitHub</a>.</p>
<p>With the release of version 1.1, it was a complete re-engineering effort to not only maintain parity with the .NET version, which had changed quite a bit since the Reactive Extensions for JavaScript was first released.&nbsp; Not only did we maintain parity with the .NET APIs, we also made an effort to make it feel more like JavaScript, but camel-casing the names to be more inline with JavaScript itself. For example, the old way of doing things with version 1.0 with C# style API calls: </p>
<script src="http://gist.github.com/2425214.js"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-2425214" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c1">// Create observable for a single value</span></div><div class='line' id='LC2'><span class="kd">var</span> <span class="nx">observable</span> <span class="o">=</span> <span class="nx">Rx</span><span class="p">.</span><span class="nx">Observable</span><span class="p">.</span><span class="nx">Return</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="c1">// Subscribe to Observable</span></div><div class='line' id='LC5'><span class="kd">var</span> <span class="nx">subscription</span> <span class="o">=</span> <span class="nx">observable</span><span class="p">.</span><span class="nx">Subscribe</span><span class="p">(</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">x</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">x</span><span class="p">);</span></div><div class='line' id='LC7'><span class="p">});</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2425214/9a8243570fc96329d6308be5286e111038d43399/rx-old.js" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2425214#file_rx_old.js" style="float:right;margin-right:10px;color:#666">rx-old.js</a>
            <a href="https://gist.github.com/2425214">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript>
<p>Becomes camel cased to fit more in line with JavaScript norms.&nbsp; This move made us rename some of the methods which collide with JavaScript reserved words such as Return =&gt; returnvalue, Catch =&gt; catchException.</p>
<script src="http://gist.github.com/2762919.js"></script><noscript><link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"><div id="gist-2762919" class="gist">

        <div class="gist-file">
          <div class="gist-data gist-syntax">
              <div class="highlight"><pre><div class='line' id='LC1'><span class="c1">// Create observable for a single value</span></div><div class='line' id='LC2'><span class="kd">var</span> <span class="nx">observable</span> <span class="o">=</span> <span class="nx">Rx</span><span class="p">.</span><span class="nx">Observable</span><span class="p">.</span><span class="nx">returnValue</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span></div><div class='line' id='LC3'><br/></div><div class='line' id='LC4'><span class="c1">// Subscribe to Observable</span></div><div class='line' id='LC5'><span class="kd">var</span> <span class="nx">subscription</span> <span class="o">=</span> <span class="nx">observable</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">x</span><span class="p">)</span> <span class="p">{</span></div><div class='line' id='LC6'>&nbsp;&nbsp;&nbsp;&nbsp;<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">x</span><span class="p">);</span></div><div class='line' id='LC7'><span class="p">});</span></div></pre></div>
          </div>

          <div class="gist-meta">
            <a href="https://gist.github.com/raw/2762919/e3b38b5ad263543f12d7f69327dfc91396770836/rxjs-new.js" style="float:right;">view raw</a>
            <a href="https://gist.github.com/2762919#file_rxjs_new.js" style="float:right;margin-right:10px;color:#666">rxjs-new.js</a>
            <a href="https://gist.github.com/2762919">This Gist</a> brought to you by <a href="http://github.com">GitHub</a>.
          </div>
        </div>
</div>
</noscript>
<p>The Reactive Extensions for JavaScript V2 Beta once again tries for parity with the Reactive Extensions for .NET V2 Beta in terms of APIs, but differs as with the current release, we still support the old schedulers of Immediate, CurrentThread and Timeout.&nbsp; We’ve also added new experimental operators such as imperative operators as if, case, for, while and do while, as well as others such as fork join.&nbsp; I’ll go over more in detail in subsequent posts.</p>
<h1>Conclusion</h1>
<p>In the coming posts, I’ll go over in detail, reintroducing the Reactive Extensions for JavaScript, why it’s useful and where you can take advantage of it.&nbsp; Check us out on <a href="https://github.com/reactive-extensions">GitHub</a>, download us via <a href="https://nuget.org/packages?q=RxJS">NuGet</a> or the <a href="http://msdn.microsoft.com/en-us/data/gg577612">MSDN Data Developer Center</a>, and give feedback on the <a href="http://social.msdn.microsoft.com/Forums/en-US/rx/threads">forum</a>!</p>
<div class="shr-publisher-261"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fmatthewpodwysocki%2F2012%2F05%2F21%2Fa-gentle-reintroduction-to-the-reactive-extensions-for-javascript%2F' data-shr_title='A+Gentle+Reintroduction+to+the+Reactive+Extensions+for+JavaScript'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fmatthewpodwysocki%2F2012%2F05%2F21%2Fa-gentle-reintroduction-to-the-reactive-extensions-for-javascript%2F' data-shr_title='A+Gentle+Reintroduction+to+the+Reactive+Extensions+for+JavaScript'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fmatthewpodwysocki%2F2012%2F05%2F21%2Fa-gentle-reintroduction-to-the-reactive-extensions-for-javascript%2F' data-shr_title='A+Gentle+Reintroduction+to+the+Reactive+Extensions+for+JavaScript'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/Ma5kmHcv6nc" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/h22d8dbLR0s" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/matthewpodwysocki/2012/05/21/a-gentle-reintroduction-to-the-reactive-extensions-for-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
					<feedburner:origLink>http://codebetter.com/matthewpodwysocki/2012/05/21/a-gentle-reintroduction-to-the-reactive-extensions-for-javascript/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/Ma5kmHcv6nc/</feedburner:origLink></item>
	      
    	<item>
		<title>node.js in the cloud with Windows Azure activities in Oslo</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/JtGl9zRSOHk/</link>
		<comments>http://codebetter.com/glennblock/2012/05/21/node-js-in-the-cloud-with-windows-azure-activities-in-oslo/#comments</comments>
		<pubDate>Mon, 21 May 2012 14:14:29 +0000</pubDate>
		<dc:creator>Glenn Block</dc:creator>
				<category><![CDATA[azure]]></category>
		<category><![CDATA[node.js]]></category>
			<guid isPermaLink="false">http://codebetter.com/glennblock/?p=417</guid>
					<description><![CDATA[After GOTO finishes, this week I am heading to Oslo for node.js and Azure action. On Friday eve 5/25, I’ll be delivering a talk on node.js in Windows Azure at nnug-Oslo. On Saturday 5/26, I’ll be giving a full day&#160;&#8230; <a href="http://codebetter.com/glennblock/2012/05/21/node-js-in-the-cloud-with-windows-azure-activities-in-oslo/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>After GOTO finishes, this week I am heading to Oslo for node.js and Azure action.</p>
<ul>
<li>On Friday eve 5/25, I’ll be delivering a <a href="http://nnug.no/Avdelinger/Oslo/Moter/NNUG-Oslo---Brukergruppemote-25-mai-2012/">talk</a> on node.js in Windows Azure at nnug-Oslo.</li>
<li>On Saturday 5/26, I’ll be giving a full day <a href="http://www.meetup.com/NodeJSOslo/events/65004992/">node.js on Azure workshop</a>. We’ll spend the first half of the day walking through together how to deploy node apps to Windows Azure (even using GIT based deployment on a Mac!) and access Azure services from node. In the second half we’ll have a node.js/ Azure hackathon after which prizes will be given for the best apps.</li>
</ul>
<p>If you are in the area and interested in node.js, come on out!</p>
<div class="shr-publisher-417"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F21%2Fnode-js-in-the-cloud-with-windows-azure-activities-in-oslo%2F' data-shr_title='node.js+in+the+cloud+with+Windows+Azure+activities+in+Oslo'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F21%2Fnode-js-in-the-cloud-with-windows-azure-activities-in-oslo%2F' data-shr_title='node.js+in+the+cloud+with+Windows+Azure+activities+in+Oslo'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F21%2Fnode-js-in-the-cloud-with-windows-azure-activities-in-oslo%2F' data-shr_title='node.js+in+the+cloud+with+Windows+Azure+activities+in+Oslo'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/RD0JNdHjhGo" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/JtGl9zRSOHk" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/glennblock/2012/05/21/node-js-in-the-cloud-with-windows-azure-activities-in-oslo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
					<feedburner:origLink>http://codebetter.com/glennblock/2012/05/21/node-js-in-the-cloud-with-windows-azure-activities-in-oslo/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/RD0JNdHjhGo/</feedburner:origLink></item>
	      
    	<item>
		<title>Slice of Life: Converting my Personal Site</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/1YDauDwWpzg/</link>
		<comments>http://codebetter.com/drusellers/2012/05/13/slice-of-life-converting-my-personal-site/#comments</comments>
		<pubDate>Sun, 13 May 2012 16:32:36 +0000</pubDate>
		<dc:creator>Dru Sellers</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
			<guid isPermaLink="false">http://codebetter.com/drusellers/?p=265</guid>
					<description><![CDATA[Over the last few months I have been having a lot of fun converting my personal site (http://drusellers.com) from a pure static html site, to one that uses a back end server side language. When I first started the main&#160;&#8230; <a href="http://codebetter.com/drusellers/2012/05/13/slice-of-life-converting-my-personal-site/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Over the last few months I have been having a lot of fun converting my personal site (http://drusellers.com) from a pure static html site, to one that uses a back end server side language.</p>
<p>When I first started the main purpose was to learn a little more about python. So I started off using Flask, a micro framework for python. Flask is a lot like Sinatra for ruby and the comparison was a lot of fun because my good friend Ryan Rauh (RyRy) was writing a site in Sinatra at the time so we were able to compare and contrast the two approaches quite easily.</p>
<p>As I learned more about flask and all that it could do, I was impressed by how much I could do with so little. It served as a solid reminder that we should strive for simpler solutions.</p>
<p>In addition to learning python I also took the time to dive into LESS. Organizing the CSS content of applications has always been difficult for me. Finally, with LESS I had variables and the ability to nest selectors. Basically, all of the things that I have wanted CSS to do for a very long time. I started out using the runtime compilation modes of LESS, but as I learned more I eventually switched to running the watch mode on the compiler and then stripping that functionality out of the app. Right now, I really like this approach. It feels more like PROD vs DEV, but I still have the ability to iterate quickly. The real choice to use LESS, was that the popular CSS framework from Twitter called Bootstrap had just launched. By studying their approach and trying to deconstruct things I have learned a lot about CSS and its application to better CSS approaches.</p>
<p>But as with all things in the technical world, a change was on the horizon. That change was SASS/SCSS. RyRy read a post somewhere comparing SCSS and LESS and he came away with the impression that SCSS RULED, and LESS DROOLED. This was one of those moments, where I gave RyRy a stern look and then sat down to start converting my website from LESS to SCSS, because when the guy you ask all of your questions too, changes directions sometimes its just easier to go with the flow. Thankfully it wasn&#8217;t that hard, allowed me to revisit my CSS and improve things further.</p>
<p>Around the same time, I discovered semantic.gs, a SCSS friendly grid system, finally I can get rid of the BS classes like span-4 and what not that have been plaguing me since I first found blueprint.css and 960grid. Whoot! I have been able to further clean up the website&#8217;s CSS approach.</p>
<p>Well, of course the project can come to a close quite that simply. After improving my CSS and getting an understanding of python, I of course, had to completely rebuild it something new and shiny. Damn, my attention span.</p>
<p>So, yeah. Node.js the new shiny language/framework. My JavaScript skills have always suffered, so I rationalized changing my backend code to JavaScript as a means to improve my JS skillset. So, I converted my site again, learned a lot about JavaScript in the process, melted my brain trying to get things to work in this under powered language (under powered because I am used to my language providing much more to me).</p>
<p>So now my site is running Node.js &#8211; its a whole lot cleaner and easier to work on. I love how simple the underlying code is, and I have really learned a lot about some of the new languages and frameworks out there.</p>
<div class="shr-publisher-265"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F05%2F13%2Fslice-of-life-converting-my-personal-site%2F' data-shr_title='Slice+of+Life%3A+Converting+my+Personal+Site'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F05%2F13%2Fslice-of-life-converting-my-personal-site%2F' data-shr_title='Slice+of+Life%3A+Converting+my+Personal+Site'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F05%2F13%2Fslice-of-life-converting-my-personal-site%2F' data-shr_title='Slice+of+Life%3A+Converting+my+Personal+Site'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/vpokd2F_W2o" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/1YDauDwWpzg" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/drusellers/2012/05/13/slice-of-life-converting-my-personal-site/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
					<feedburner:origLink>http://codebetter.com/drusellers/2012/05/13/slice-of-life-converting-my-personal-site/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/vpokd2F_W2o/</feedburner:origLink></item>
	      
    	<item>
		<title>Azure SDK for node 0.5.4 is out! More secure and now with less angle brackets</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/hcomT2yQ_ok/</link>
		<comments>http://codebetter.com/glennblock/2012/05/12/azure-sdk-for-node-0-5-4-is-out-more-secure-and-now-with-less-angle-brackets/#comments</comments>
		<pubDate>Sat, 12 May 2012 18:33:15 +0000</pubDate>
		<dc:creator>Glenn Block</dc:creator>
				<category><![CDATA[node.js]]></category>
			<guid isPermaLink="false">http://codebetter.com/glennblock/?p=411</guid>
					<description><![CDATA[As Yavor said, Azure SDK for node 0.5.4 is out with a bunch of goodies! Closing a security hole Recently a vulnerability was detected in node.exe that could theoretically allow an attacker to perform a header-spoofing attack. Version 0.6.17 contains&#160;&#8230; <a href="http://codebetter.com/glennblock/2012/05/12/azure-sdk-for-node-0-5-4-is-out-more-secure-and-now-with-less-angle-brackets/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>As Yavor said, <a href="http://hashtagfail.com/post/22865195229/node-sdk-0-5-4">Azure SDK for node 0.5.4 is out</a> with a bunch of goodies!</p>
<h1>Closing a security hole</h1>
<p>Recently a <a href="http://blog.nodejs.org/2012/05/07/http-server-security-vulnerability-please-upgrade-to-0-6-17/">vulnerability</a> was detected in node.exe that could theoretically allow an attacker to perform a header-spoofing attack. Version 0.6.17 contains a fix for this attack. We take security very seriously, so we’re releasing this update which includes node 0.6.17 to remove the vulnerability.</p>
<p>Please go <a href="http://www.microsoft.com/web/gallery/install.aspx?appid=azurenodepowershell">download </a>the latest bits to remove this vulnerability!</p>
<p><strong>Less angle brackets, more YAML</strong></p>
<p><a href="https://github.com/tjanczuk/iisnode">iisnode</a> offers some really nice hosting capabilities like spinning up and managing multiple node procs, allowing access to logs over HTTP, providing good debugger errors in the browser for diagnostics and supporting node-inspector for debugging.</p>
<p>To access any of these benefits however you have to travel the sea of angle brackets known as web.config. For .NET / Windows developers, this is the norm. However, we heard a lot of feedback from folks in the node-a-verse, in particular coming from on a Mac / *nix that this feels very strange that they have use web.config in order to config node-specific things in Windows Azure, especially in light of the other offerings out there. Looking around we saw that a common pattern was to use a simple key-value format for specifying similar settings with <a href="http://yaml.org/">YAML</a> being a very popular format.</p>
<h2>iisnode.yml</h2>
<p>And so our team <a href="https://github.com/tjanczuk/iisnode/issues/158">racked our brains</a> a bit, got a bunch of feedback and <a href="http://tomasz.janczuk.org/2012/05/yaml-configuration-support-in-iisnode.html">iisnode.yml</a> was born and implemented by Tomek! iisnode.yml is an optional file that sits along side web.config. It allows you to set all of our iisnode <a href="https://github.com/tjanczuk/iisnode/blob/master/src/samples/configuration/iisnode.yml">settings</a> without having to ever touch web.config. Below is a really simple example.</p>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px"><span style="color: #800000">#</span> <span style="color: #800000">This</span> <span style="color: #800000">is</span> <span style="color: #800000">a</span> <span style="color: #800000">really</span> <span style="color: #800000">simple</span> <span style="color: #800000">iisnode</span>.<span style="color: #800000">yml</span> <span style="color: #800000">file</span></pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px"></pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px"><span style="color: #800000">node</span>_<span style="color: #800000">env</span>: <span style="color: #800000">development</span></pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px"><span style="color: #800000">devErrorsEnabled</span>: <span style="color: #800000">true</span></pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px"><span style="color: #800000">logggingEnabled</span>: <span style="color: #800000">true</span></pre>
<p>&nbsp;</p>
<p>The settings set the node_env environment variable to development, enables logging all node.exe output and enables developer errors.</p>
<p>For example, the code below has an error in that it requires a module that does not exist, also it uses spaces in the module name.</p>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px"><span style="color: #0000ff">var</span> http = require('http');</pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px"><span style="color: #0000ff">var</span> notPresent = require('some awesome module');</pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px">http.createServer(<span style="color: #0000ff">function</span> (req, res) {</pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px">  <span style="color: #0000ff">throw</span> "<span style="color: #8b0000">error</span>";</pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px">  res.writeHead(200, {'Content-Type': 'text/plain'});</pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px">  notPresent.doSomethingAwesome();</pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px">  res.end('Hello World Again\n');</pre>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px">}).listen(process.env.PORT);</pre>
<p>&nbsp;</p>
<p>If I don’t enable devErrors this is what I get when I do a request.</p>
<p><a href="http://codebetter.com/glennblock/files/2012/05/Screen-Shot-2012-05-12-at-11.10.45-AM.png"><img style="margin: 0px 0px 24px;padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://codebetter.com/glennblock/files/2012/05/Screen-Shot-2012-05-12-at-11.10.45-AM_thumb.png" alt="Screen Shot 2012-05-12 at 11.10.45 AM" width="587" height="209" border="0" /></a></p>
<p>However, look at what I get when I enable devErrors with logging.</p>
<p><a href="http://codebetter.com/glennblock/files/2012/05/Screen-Shot-2012-05-12-at-11.04.40-AM.png"><img style="margin: 0px 0px 24px;padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px" src="http://codebetter.com/glennblock/files/2012/05/Screen-Shot-2012-05-12-at-11.04.40-AM_thumb.png" alt="Screen Shot 2012-05-12 at 11.04.40 AM" width="563" height="387" border="0" /></a></p>
<p>Above you an see that an error occurred because it could not find my wacky module.</p>
<p>Developer errors is a pretty cool feature that allows iis to output in the response any errors that occurred right in the browser. Combined with logging, it’s really useful for debugging on a remote/staging server.</p>
<p>Of course you don’t want anyone seeing that in your live production site, so you should probably shut that off.</p>
<h2>myfile.yml</h2>
<p>By convention we look for iisnode.yml. If you are not happy with that name however, you can set your own name in the iisnode element of web.config by using the configOverrides property.</p>
<pre style="background-color: #ffffff;margin: 0em;width: 100%;font-family: consolas,'Courier New',courier,monospace;font-size: 12px"><span style="color: #0000ff">&lt;</span><span style="color: #800000">iisnode</span> <span style="color: #ff0000">configOverrides</span>=<span style="color: #0000ff">"myfile.yml"</span><span style="color: #0000ff">/&gt;</span></pre>
<p><strong>Note</strong>: configOverrides also allows you to do environment variable expansion. Thus instead of having a static file name you can have a name that includes an environment variable value. More on that in the future.</p>
<p><strong>But wait, don’t I still need a web.config when I publish to Windows Azure?</strong></p>
<p>Great question! Today you still need a web.config though as Tomek said that can be boilerplate and you don’t have to look at it. Tomorrow however…. <img src='http://codebetter.com/glennblock/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Go get the latest SDK <a href="http://www.microsoft.com/web/gallery/install.aspx?appid=azurenodepowershell">here</a>.</p>
<div class="shr-publisher-411"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F12%2Fazure-sdk-for-node-0-5-4-is-out-more-secure-and-now-with-less-angle-brackets%2F' data-shr_title='Azure+SDK+for+node+0.5.4+is+out%21+More+secure+and+now+with+less+angle+brackets'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F12%2Fazure-sdk-for-node-0-5-4-is-out-more-secure-and-now-with-less-angle-brackets%2F' data-shr_title='Azure+SDK+for+node+0.5.4+is+out%21+More+secure+and+now+with+less+angle+brackets'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F12%2Fazure-sdk-for-node-0-5-4-is-out-more-secure-and-now-with-less-angle-brackets%2F' data-shr_title='Azure+SDK+for+node+0.5.4+is+out%21+More+secure+and+now+with+less+angle+brackets'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/_bH0Q0BRVV8" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/hcomT2yQ_ok" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/glennblock/2012/05/12/azure-sdk-for-node-0-5-4-is-out-more-secure-and-now-with-less-angle-brackets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
					<feedburner:origLink>http://codebetter.com/glennblock/2012/05/12/azure-sdk-for-node-0-5-4-is-out-more-secure-and-now-with-less-angle-brackets/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/_bH0Q0BRVV8/</feedburner:origLink></item>
	      
    	<item>
		<title>Honored to have participated in the ACT Fly-In</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/Hm6nw7NPb74/</link>
		<comments>http://codebetter.com/johnvpetersen/2012/05/11/honored-have-participated-in-the-act-fly-in/#comments</comments>
		<pubDate>Fri, 11 May 2012 12:03:47 +0000</pubDate>
		<dc:creator>johnvpetersen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ACT]]></category>
		<category><![CDATA[Privacy]]></category>
		<category><![CDATA[Regulation]]></category>
		<category><![CDATA[Spectrum]]></category>
			<guid isPermaLink="false">http://codebetter.com/johnvpetersen/?p=469</guid>
					<description><![CDATA[You can read about the event here. Every so often, you get the opportunity to participate in a process that affords you the opportunity to talk to those who make policy that affects our personal and business lives. During the&#160;&#8230; <a href="http://codebetter.com/johnvpetersen/2012/05/11/honored-have-participated-in-the-act-fly-in/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>You can read about the event <a href="http://actonline.org/act-blog/archives/2465" target="_blank">here</a>.</p>
<p><a href="http://www.flickr.com/photos/77818064@N03/7006537886/sizes/l/in/photostream/" target="_blank"><img class="alignnone" src="http://actonline.org/act-blog/files/ACT-at-White-House-300x186.jpg" alt="" width="300" height="186" /></a></p>
<p>Every so often, you get the opportunity to participate in a process that affords you the opportunity to talk to those who make policy that affects our personal and business lives. During the Fly-In, a group of us engaged with members of Congress on topics that ranged from privacy, bandwidth and entrepreneurship.</p>
<p>My two big issues: privacy and the available bandwidth spectrum.</p>
<p><strong>Privacy:</strong></p>
<p>What people need is the ability to provide informed consent. It&#8217;s very difficult, if not impossible, for government to formulate regulations that covers every conceivable behavior. All these regulations serve to do is stiffle innovation and harm those that play by the rules. What we do know when we see it is bad conduct. The FTC has broad enforcement and police power and they need to use the power Congress gave them. Punish the bad actors and make an example out of them to provide the necessary incentives to handle online privacy the right way.</p>
<p><strong>Bandwidth Spectrum:</strong></p>
<p>Recently, <a href="http://news.heartland.org/newspaper-article/2012/02/24/congress-mandates-fcc-spectrum-auctions" target="_blank">Congress mandated FCC Spectrum Auctions</a>. Are you tired of dead spots and sluggish performance over 3G/4G networks? Did you know the carriers stand at the ready to fund the billions of $&#8217;s necessary to put up and light up more towers? To make that work, the amount of available bandwidth has to be increased. Congress has taken an important first step &#8211; but more needs to be done. Increasingly, we rely on more than just plain text. Mobile Apps are providing (at least are trying to provide) rich content. What&#8217;s holding things back? Lack of available bandwidth. The bandwidth is out there, we just need to make it available and use it.</p>
<div class="shr-publisher-469"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F05%2F11%2Fhonored-have-participated-in-the-act-fly-in%2F' data-shr_title='Honored+to+have+participated+in+the+ACT+Fly-In'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F05%2F11%2Fhonored-have-participated-in-the-act-fly-in%2F' data-shr_title='Honored+to+have+participated+in+the+ACT+Fly-In'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F05%2F11%2Fhonored-have-participated-in-the-act-fly-in%2F' data-shr_title='Honored+to+have+participated+in+the+ACT+Fly-In'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/UCkoIV83oIc" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/Hm6nw7NPb74" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/johnvpetersen/2012/05/11/honored-have-participated-in-the-act-fly-in/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
					<feedburner:origLink>http://codebetter.com/johnvpetersen/2012/05/11/honored-have-participated-in-the-act-fly-in/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/UCkoIV83oIc/</feedburner:origLink></item>
	      
    	<item>
		<title>Node.js and Azure on .NET Rocks!</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/K8fPgbI1ubM/</link>
		<comments>http://codebetter.com/glennblock/2012/05/09/node-js-and-azure-on-net-rocks/#comments</comments>
		<pubDate>Wed, 09 May 2012 08:26:28 +0000</pubDate>
		<dc:creator>Glenn Block</dc:creator>
				<category><![CDATA[azure]]></category>
		<category><![CDATA[node.js]]></category>
			<guid isPermaLink="false">http://codebetter.com/glennblock/?p=405</guid>
					<description><![CDATA[Recently I had the privilege to talk to my good friends Richard and Carl about the work we’re doing enabling Node.js development with Windows Azure along with our friends in the node community. It was also a great opportunity for&#160;&#8230; <a href="http://codebetter.com/glennblock/2012/05/09/node-js-and-azure-on-net-rocks/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Recently I had the privilege to talk to my good friends Richard and Carl about the work we’re doing enabling Node.js development with Windows Azure along with our friends in the node community. It was also a great opportunity for me to practice my new subdued Glenn persona <img src='http://codebetter.com/glennblock/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  You have to listen to believe it!</p>
<p><a href="http://dotnetrocks.com/default.aspx?showNum=763">http://dotnetrocks.com/default.aspx?showNum=763</a></p>
<blockquote><p>Carl and Richard talk to Glenn Block about node.js on Azure. Glenn digs into how node.js has grown in popularity, and points to the Cloud9 IDE as a development environment in the Cloud as an example of a node.js application &#8211; which happens to be able to build node.js applications. And Cloud 9 can deploy node.js to Azure. The conversation digs into the Azure stack and the diversity of technologies (including node.js) that run great in the cloud.</p>
</blockquote>
<div class="shr-publisher-405"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F09%2Fnode-js-and-azure-on-net-rocks%2F' data-shr_title='Node.js+and+Azure+on+.NET+Rocks%21'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F09%2Fnode-js-and-azure-on-net-rocks%2F' data-shr_title='Node.js+and+Azure+on+.NET+Rocks%21'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F09%2Fnode-js-and-azure-on-net-rocks%2F' data-shr_title='Node.js+and+Azure+on+.NET+Rocks%21'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/ViM3ELV3PNc" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/K8fPgbI1ubM" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/glennblock/2012/05/09/node-js-and-azure-on-net-rocks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
					<feedburner:origLink>http://codebetter.com/glennblock/2012/05/09/node-js-and-azure-on-net-rocks/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/ViM3ELV3PNc/</feedburner:origLink></item>
	      
    	<item>
		<title>I’ll be at GOTO CPH and QCON NYC spreading the node.js love</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/afB-d-njGOY/</link>
		<comments>http://codebetter.com/glennblock/2012/05/04/ill-be-at-goto-cph-and-qcon-nyc-spreading-the-node-js-love/#comments</comments>
		<pubDate>Fri, 04 May 2012 08:06:56 +0000</pubDate>
		<dc:creator>Glenn Block</dc:creator>
				<category><![CDATA[azure]]></category>
		<category><![CDATA[node.js]]></category>
			<guid isPermaLink="false">http://codebetter.com/glennblock/?p=383</guid>
					<description><![CDATA[Conference season is coming again. I am excited this year that I’ll be finally speaking at goto AND that I’ll be speaking at the first QCon NYC. The topic, well you guessed it, node.js and Windows Azure. May 21-23 First&#160;&#8230; <a href="http://codebetter.com/glennblock/2012/05/04/ill-be-at-goto-cph-and-qcon-nyc-spreading-the-node-js-love/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Conference season is coming again. I am excited this year that I’ll be finally speaking at goto AND that I’ll be speaking at the <strong>first</strong> QCon NYC. The topic, well you guessed it, node.js and Windows Azure.</p>
<p><strong>May 21-23</strong></p>
<p style="text-align: center"><a href="http://gotocon.com/cph-2012/"><img class="aligncenter" style="border-style: initial;border-color: initial;border-width: 0px" src="http://codebetter.com/glennblock/files/2012/05/image.png" alt="image" width="368" height="140" border="0" /></a></p>
<p style="text-align: left">First stop will be Copenhagen where I will be <a href="http://gotocon.com/cph-2012/speaker/Glenn+Block">speaking</a> at goto in the “Microsoft, beyond the echo chamber track”  I am really looking forward to this event. I’ve watched it for years before when it was JAOO but never got the chance to attend. I am happy to say this year that will be changing. I hope to see you there!</p>
<p>Presentation: <a href="http://gotocon.com/cph-2012/presentation/Breaking%20the%20Barrier%20with%20Node.js%20on%20Windows%20and%20Azure">Breaking the Barrier with Node.js on Windows and Azure</a></p>
<p><strong>June 18-22</strong></p>
<p style="text-align: center"><a href="http://codebetter.com/glennblock/files/2012/05/image1.png"><img class="aligncenter" style="margin-top: 0px;margin-bottom: 24px;padding-left: 0px;padding-right: 0px;padding-top: 0px;border-style: initial;border-color: initial;border-width: 0px" src="http://codebetter.com/glennblock/files/2012/05/image_thumb.png" alt="image" width="316" height="170" border="0" /></a></p>
<p>I’ll be <a href="http://qconnewyork.com/qcon-nyc-2012/speaker/Glenn+Block">speaking</a> at QCon NYC in the “Battle of the Clouds track”. If you are planning to attend, you can save $100 by using this promotion code when you register: <strong>BLOC100</strong></p>
<p>Presentation: <a href="http://qconnewyork.com/qcon-nyc-2012/presentation/Unlock+your+Inner+Node.js+in+the+Cloud+with+Windows+Azure">&#8220;Unlock your Inner Node.js in the Cloud with Windows Azure&#8221;</a>. I’m planning to show some really cool stuff that we have coming down the pike soon at this event, so be there!</p>
<p>After the event, I’ll also be delivering two half day tutorials on node.js.</p>
<ul>
<li>“node.js, jumping in with both feet”. This tutorial will be a basic primer around node.js and take you from 0 to 60 with node.js development. It will cover the basics, common practices as well as popular third party modules.</li>
<li>“node.js in Windows Azure”. In this tutorial we will dive into deploying node.js applications to Windows Azure as well as using Azure storage services and ServiceBus from within your node.js apps. We’ll also cover development tools like <a href="http://c9.io">Cloud9 IDE</a> that you can use for deploying node apps to Azure.</li>
</ul>
<p>If you are looking to get up to speed with node or to start deploying node apps to Azure come to these tutorials.</p>
<p>While I am in town for both events I’ll be doing a bunch of user group meetups and such. I’ll cover that in my next post</p>
<div class="shr-publisher-383"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F04%2Fill-be-at-goto-cph-and-qcon-nyc-spreading-the-node-js-love%2F' data-shr_title='I%26rsquo%3Bll+be+at+GOTO+CPH+and+QCON+NYC+spreading+the+node.js+love'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F04%2Fill-be-at-goto-cph-and-qcon-nyc-spreading-the-node-js-love%2F' data-shr_title='I%26rsquo%3Bll+be+at+GOTO+CPH+and+QCON+NYC+spreading+the+node.js+love'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fglennblock%2F2012%2F05%2F04%2Fill-be-at-goto-cph-and-qcon-nyc-spreading-the-node-js-love%2F' data-shr_title='I%26rsquo%3Bll+be+at+GOTO+CPH+and+QCON+NYC+spreading+the+node.js+love'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/AN2T1dzoesY" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/afB-d-njGOY" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/glennblock/2012/05/04/ill-be-at-goto-cph-and-qcon-nyc-spreading-the-node-js-love/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
					<feedburner:origLink>http://codebetter.com/glennblock/2012/05/04/ill-be-at-goto-cph-and-qcon-nyc-spreading-the-node-js-love/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/AN2T1dzoesY/</feedburner:origLink></item>
	      
    	<item>
		<title>Cron and AppEngine</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/lebVhTTWc9E/</link>
		<comments>http://codebetter.com/kylebaley/2012/04/28/cron-and-appengine-2/#comments</comments>
		<pubDate>Sat, 28 Apr 2012 15:52:14 +0000</pubDate>
		<dc:creator>Kyle Baley</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Google App Engine]]></category>
			<guid isPermaLink="false">http://codebetter.com/kylebaley/?p=285</guid>
					<description><![CDATA[Quick PSA on using cron jobs with Google App Engine because it almost wreaked havoc for us. App Engine has a lovely feature of having different versions of your app. You can upload a new version but not make it&#160;&#8230; <a href="http://codebetter.com/kylebaley/2012/04/28/cron-and-appengine-2/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Quick PSA on using cron jobs with <a href="https://developers.google.com/appengine/docs/java/config/cron" target="_blank">Google App Engine</a> because it almost wreaked havoc for us.</p>
<p>App Engine has a lovely feature of having different versions of your app. You can upload a new version but not make it the default until you’re good and ready. We do this all the time for deployment. Deploy to a new version and try it out, then make it the default when we’re ready to unleash it. Often, we deploy to the new version a day or so in advance.</p>
<p>Cron jobs, it seems, are handled outside this versioning mechanism. If you upload a new cron.xml file, it’s active. Right now. Doesn’t matter if the version it was deployed in is the default or not. As soon as it’s uploaded, it’s the new cron-ness.</p>
<p>Where this almost bit us is that we added a new cron job in our most recent release (deployed yesterday but not active) to use a <a href="https://developers.google.com/appengine/docs/java/backends/" target="_blank">dynamic backend</a>. As soon as the cron job got uploaded, it started running. I didn’t notice until this morning when our backend usage reflected the new cron job. Some <a href="http://www.mail-archive.com/google-appengine@googlegroups.com/msg34752.html" target="_blank">quick research</a> and here we are.</p>
<p>What this means long term is that cron.xml is no longer going to be deployed as part of our application anymore. It now becomes an entirely separate process. I’m a little annoyed that we have to wait until we pull the trigger on the new version before we can upload the new cron.xml but it’s a quick step.</p>
<p>Kyle the Mis-scheduled</p>
<div class="shr-publisher-285"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F28%2Fcron-and-appengine-2%2F' data-shr_title='Cron+and+AppEngine'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F28%2Fcron-and-appengine-2%2F' data-shr_title='Cron+and+AppEngine'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F28%2Fcron-and-appengine-2%2F' data-shr_title='Cron+and+AppEngine'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/PhmgQdh-yFY" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/lebVhTTWc9E" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/kylebaley/2012/04/28/cron-and-appengine-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
					<feedburner:origLink>http://codebetter.com/kylebaley/2012/04/28/cron-and-appengine-2/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/PhmgQdh-yFY/</feedburner:origLink></item>
	      
    	<item>
		<title>State Machines and Business Users</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/6JI43tMeaLs/</link>
		<comments>http://codebetter.com/gregyoung/2012/04/24/state-machines-and-business-users-2/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 09:21:13 +0000</pubDate>
		<dc:creator>gregyoung</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
			<guid isPermaLink="false">http://codebetter.com/gregyoung/?p=297</guid>
					<description><![CDATA[I was at a workshop over the weekend talking about the use of Finite State Machines as coordination mechanisms for systems. These things might be called sagas, activities, workflows, process managers (my preferred term lately from PEI), orchestrations, choreographers, and&#160;&#8230; <a href="http://codebetter.com/gregyoung/2012/04/24/state-machines-and-business-users-2/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I was at a workshop over the weekend talking about the use of Finite State Machines as coordination mechanisms for systems. These things might be called sagas, activities, workflows, process managers (my preferred term lately from PEI), orchestrations, choreographers, and I am sure I am leaving out a few.</p>
<p>One of the guys in the talk (quite knowledgable) brought up that they used to use petri nets for this as well as pure finite state machines and there had been a push to more procedural mechanisms as business users don&#8217;t think in terms of finite state machines. I noted that while we have been moving to more procedural methods, as most of these procedural methods are in their hearts asynchronous our procedural techniques tend to be domain specific languages that internally generate state machines anyways, often based in the join calculus (think futures or the async keyword in C# when joining).</p>
<p>However later in the day I had a realization connecting two things. We like to describe business situations in gherkin style (not strict) specifications.</p>
<p>Given: Some initial starting point<br />
When: Something happens<br />
Then: Something occurred</p>
<p>We as an industry have been very successful getting specifications written in this style. We regularly do analysis and write acceptance criteria using this style. Business users seem to have been fairly capable of understanding it.</p>
<p>This style is basically describing a state machine. </p>
<p>Given: some initial state<br />
When: a stimulus<br />
Then: Something occurred (message/transition depending on style of testing)</p>
<p>How can we be so successful with this style of specification and in the next breath say that business users can&#8217;t understand state machines? The trick is they don&#8217;t understand the actual machine but they understand (and can specify very well) the exterior behaviours of such a machine.</p>
<p>Try getting a business user to create for you the state machine to control a simple DVD player for you. Likely they will scratch their heads and politely become very busy so they won&#8217;t be able to attend the next meeting. Try getting them to specify </p>
<p>Given a video is playing<br />
When fast forward is pressed<br />
Then the play goes at double speed</p>
<p>Maybe the problem here that caused our move towards procedural style controllers was the goal all the middleware seems to push of having business users <strong>writing</strong> the activities as opposed to reading about/specifying/understanding them. I have yet to see in all the organizations I have been to a single one where the dream of having business users creating these types of long running procedures actually panned out. <em>to be fair: I have seen it work but the business user had formerly been a developer and BA</em></p>
<div class="shr-publisher-297"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fgregyoung%2F2012%2F04%2F24%2Fstate-machines-and-business-users-2%2F' data-shr_title='State+Machines+and+Business+Users'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fgregyoung%2F2012%2F04%2F24%2Fstate-machines-and-business-users-2%2F' data-shr_title='State+Machines+and+Business+Users'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fgregyoung%2F2012%2F04%2F24%2Fstate-machines-and-business-users-2%2F' data-shr_title='State+Machines+and+Business+Users'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/GNAWhdpfUjA" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/6JI43tMeaLs" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/gregyoung/2012/04/24/state-machines-and-business-users-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
					<feedburner:origLink>http://codebetter.com/gregyoung/2012/04/24/state-machines-and-business-users-2/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/GNAWhdpfUjA/</feedburner:origLink></item>
	      
    	<item>
		<title>The Economics of Ergonomics</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/oijJh_Rqvvs/</link>
		<comments>http://codebetter.com/kylebaley/2012/04/22/the-economics-of-ergonomics/#comments</comments>
		<pubDate>Sun, 22 Apr 2012 22:04:39 +0000</pubDate>
		<dc:creator>Kyle Baley</dc:creator>
				<category><![CDATA[Sundry]]></category>
		<category><![CDATA[Working Remotely]]></category>
			<guid isPermaLink="false">http://codebetter.com/kylebaley/?p=281</guid>
					<description><![CDATA[Let it not be said there are no downsides to living in the Bahamas (though if you’ll permit a little boasting, a shortage of fantastic venues if you’re lucky enough to be in a band is not one of them).&#160;&#8230; <a href="http://codebetter.com/kylebaley/2012/04/22/the-economics-of-ergonomics/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Let it not be said there are no downsides to living in the Bahamas (though if you’ll permit a little boasting, a shortage of <a href="http://cocodimama.com/">fantastic venues</a> if you’re lucky enough to be in a band is not one of them).</p>
<p>The desk where I work is too high, plain and simple. So much so that I’ve recently abandoned my <a href="http://codebetter.com/kylebaley/2009/04/25/re-review-of-kinesis/">Kinesis keyboard</a> because it is not what you might consider “low form factor”. I’ve started feeling some twinges in my lower forearm that my unscientific diagnosis is attributing to the height of my hands while I type. Dumping the Kinesis has helped but it has also led to the return of stress in other areas of my hands. And no amount of raccoon skinning seems to alleviate the pain.</p>
<p>Getting a lower desk is easy enough but I’d actually like to do a little experimenting with two alternatives. Alas, neither are easily done in the Bahamas. The underlying problem is availability. The desks/equipment I want to test are not available here so I would have to order them in. Which means both shipping charges and import duties, the latter of which is a major source of income for the Bahamian government to offset the fact that there is no income tax. So returning said equipment is just not practical if it doesn’t work out. Nor is there much of a reseller market.</p>
<p>So I’m hoping I can get some comments from people who have done something similar.</p>
<h2>Adjustable height desk</h2>
<p align="left">These are, of courses, desks where you can <a href="http://www.geekdesk.com/">adjust the height</a> easily. I like the idea of these for two reasons:</p>
<ul>
<li>
<div align="left">They can be set low</div>
<li>
<div align="left">They can be set high</div>
</li>
</ul>
<p align="left">I’ve never tried a desk that you stand at but I’ve always wanted to. Working on my own, I tend to get up and wander a lot while I’m thinking. I also pace when I’m on the phone with someone for any length of time so it would be more convenient to walk up to the computer during the conversation should the need arise. (“You want to know the right pattern of plaid for a first date with your second cousin? Let me look that up.”)</p>
<p align="left">I went desk-shopping over the weekend and the closest thing I saw was in an office supply store. And it wasn’t on the showroom floor. Off in the corner of the store were the employee desks. They were all essentially plywood based, laminated desktops all mounted in warehouse style shelving frames. They sat on brackets in the frame which means you could set the height to whatever you want. It wasn’t something you could easily adjust on the fly and my wife wasn’t too thrilled at the industrial look so it was a fleeting idea at best.</p>
<h2>Command centre<a href="http://www.gizmag.com/go/4797/picture/16743/" target="_blank"><img style="border-right-width: 0px;margin: 5px;float: right;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px" alt="computer workstation furniture MYPCE Computer Workstation Furniture" align="right" src="http://ergonomicofficefurnitures.com/wp-content/uploads/2009/12/computer-workstation-furniture-MYPCE.jpg" width="213" height="240"></a></h2>
<p>This is an idea I’ve had ruminating in my head for a while now. I would get rid of the desk altogether in favour of a comfortable command-centre style or <a href="https://www.google.com/search?hl=en&amp;q=command+center+chair#q=gaming+chair&amp;hl=en&amp;prmd=imvnsr&amp;source=univ&amp;tbm=shop&amp;tbo=u&amp;sa=X&amp;ei=-j2UT7SmNcjItge2jf21Cw&amp;sqi=2&amp;ved=0CF0QrQQ&amp;bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&amp;fp=c14441ddb21d9ff7">gaming chair</a>. In front of it it, I’d mount my monitors on a couple of <a href="http://www.ergotron.com/Products/tabid/65/PRDID/9/language/en-GB/Default.aspx">flexible arms</a> somehow, possibly on the armrests or on stands on either side of the chair. The important thing is that I can slide the monitors out of my way when I want to get out of the chair, and slide them back in when I sit down.</p>
<p>The keyboard would rest either on my lap or on some flat surface on my lap. Or maybe go with a <a href="http://www.kinesis-ergo.com/freestyle.htm">split keyboard</a> (though one without a wire between the two) and have one piece mounted on each armrest. Haven’t quite worked out how the mouse would fit in though. A trackball on some little platform on the side makes sense but I’ve got one now and it doesn’t feel as productive as just a regular mouse.</p>
<p>I feel like this would be more comfortable and would reduce much of the muscle stress that seems to have become more prominent since hitting 40 earlier this year. All of this kind of makes sense in my head but the logistics of getting the stuff here is such that I don’t want to make the investment unless I’ve had a chance to try it out at least for a few days. There’s a chance my tendency to get up and wander might make this impractical. Or maybe cord management would be an ongoing problem.</p>
<p>The <a href="http://www.gizmag.com/go/4797/picture/16743/" target="_blank">device shown at right</a>, which I discovered while researching this article, is essentially what I’ve described. It’s some US$2750. Duty would add about 50% and shipping would likely bring the total price above five large. There’s another potential hurdle in that it may not be available anymore given the <a href="http://www.mypce.com" target="_blank">company’s domain</a> seems to point to a parking spot. But even building my custom version will cost enough in non-refundable cash dollars for me not to head over eBay.</p>
<p>Instead, I hunt for a standard desk about four to six inches lower than the one I’ve got. Not as exciting, possibly not as ergonomic, but easier to replace.</p>
<p>So my question to you, my honorary hillbillies, for anecdotal evidence. Have you tried either of these devices? What’s good and bad? Good return for the money or does it sit in the garage next to the Bowflex you bought in a fit of New Year’s anxiety?</p>
<p>Kyle the Unreturnable</p>
<div class="shr-publisher-281"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F22%2Fthe-economics-of-ergonomics%2F' data-shr_title='The+Economics+of+Ergonomics'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F22%2Fthe-economics-of-ergonomics%2F' data-shr_title='The+Economics+of+Ergonomics'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F22%2Fthe-economics-of-ergonomics%2F' data-shr_title='The+Economics+of+Ergonomics'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/msUCpyZ6v-Y" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/oijJh_Rqvvs" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/kylebaley/2012/04/22/the-economics-of-ergonomics/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
					<feedburner:origLink>http://codebetter.com/kylebaley/2012/04/22/the-economics-of-ergonomics/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/msUCpyZ6v-Y/</feedburner:origLink></item>
	      
    	<item>
		<title>Sunday Thought: Patient / Fast</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/odBjyIohu0w/</link>
		<comments>http://codebetter.com/drusellers/2012/04/22/sunday-thought-patient-fast/#comments</comments>
		<pubDate>Sun, 22 Apr 2012 14:38:55 +0000</pubDate>
		<dc:creator>Dru Sellers</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
			<guid isPermaLink="false">http://codebetter.com/drusellers/?p=274</guid>
					<description><![CDATA[Some times I am such a dolt. I open a new OSS project and my first thoughts are usually &#8220;This library is ^&#38;*$% it doesn&#8217;t do anything right.&#8221;  &#8220;RAGE! (╯°□°）╯︵ ┻━┻&#8221;  don&#8217;t they know that, MY WAY is better! Its&#160;&#8230; <a href="http://codebetter.com/drusellers/2012/04/22/sunday-thought-patient-fast/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Some times I am such a dolt.</p>
<p>I open a new OSS project and my first thoughts are usually &#8220;This library is ^&amp;*$% it doesn&#8217;t do anything right.&#8221; </p>
<p>&#8220;RAGE! <span style="color: #000000;font-family: sans-serif;font-size: 13px;font-style: normal;font-variant: normal;font-weight: normal;letter-spacing: normal;line-height: 19px;text-align: -webkit-center;text-indent: 0px;background-color: #f9f9f9;float: none">(╯°□°）╯︵ ┻━┻</span>&#8221;  don&#8217;t they know that, MY WAY is better!</p>
<p>Its sad, but that is exactly what I am thinking. I am on such an immediate gratification high, thanks to my 8 core, 8GB RAM, SSD, super high speed internet capable machine that I forget that not everything can be measured in sub-second latency. Things like instant on-demand movies, and Amazon 2 day shipping don&#8217;t help with my attitude either. When it comes to learning, this demand for instant gratification has, many times, gotten in the way of what it is I really want to accomplish.</p>
<p>So, I ran into this situation again this week, and after IM&#8217;ing the maintainer &#8211; complaining about how this and that worked (ok, lets be honest &#8211; I was whining like a 4 year old) &#8211; I kinda just snapped out of it. I recalled a quote from the book <a href="http://www.amazon.com/The-Toyota-Way-Management-Manufacturer/dp/0071392319">The Toyota Way</a>, where they stated that the #1 problem with new engineers is that they can&#8217;t slow down. They just want to charge into things head first and solve all of the problems. Hmm, sounds a lot like me. Except that I have 10 years underneath my belt now. So, why am I still acting like a new developer? My biggest guess, is that I haven&#8217;t really honed my process. I need more people to catch me acting this way and to call me on it. But that can be hard to find in our community, because we all tend to act this way.</p>
<p>We, developers, are always on the look out for the next shiny library or framework that we can &#8220;learn&#8221; and by learn I mean implement. We like libraries so simple that a new programmer could understand them. We don&#8217;t want a learning curve at all. I think that this is one of the reasons things like express.js, flask, and sinatra play so well in our community. You can see, immediately, how it works. They have almost no abstraction over the underlying concepts. Let&#8217;s not forget, that its the abstractions that bring the real power, and that not every abstraction is a poor or leaky one.</p>
<p>Its Sunday, which is an introspective day for me, and I want to try and improve myself. I think that if I could work on this aspect of my skills and attitude, I would become a better developer. Being a better developer is something that I want to be. Ok, so how am I going to do this. After much thought, I was reminded of a similar experience that worked well for me outside of the software development world.</p>
<p><img style="float: right" src="http://codebetter.com/drusellers/files/2012/04/patientfast.jpg" alt="Patientfast" width="149" height="200" border="0" /></p>
<p>For that last three months I have been training in <a href="http://en.wikipedia.org/wiki/Olympic_weightlifting">Olympic Lifting</a>. Now for those of you that have never performed olympic lifts, you need to know that while strength is a big part of it, skill also plays a huge part. You can&#8217;t just hoist 150 pounds over your head with out a level of skill. The snatch is an explosive lift, that requires an insane amount of patience and balance. My coach and teammates have a phrase that I have come to love. &#8221;Patient / Fast&#8221;, which means to me that you have to move fast, but at the same time be patient in the pull. It took me a long time to really grok that concept. It feels like a damn Zen <a href="http://en.wikipedia.org/wiki/K%C5%8Dan">koan</a> at times, but I keep repeating the phrase and each day it reveals itself to me a bit more.</p>
<p>So there I was, at the keyboard, about to burst a vein, when I woke myself up from my emotions, calmed down &#8211; and asked myself what would &#8220;Patient / Fast&#8221; look like here? I decided that I would patiently look through the code, asks questions to myself via comments and then go answer them, and start to understand what the code was doing, on the flip side I would be very fast to start writing, running, and debugging unit tests to get ahold of the code base. Sure enough, the code started to reveal itself to me, I could see the author&#8217;s intentions much better now. I started to build up a good amount of understanding, and was able to effectively solve my problem but was also even able to make a nice pull request back to the library that I think cleaned up a very small part of the code base. <img src='http://codebetter.com/drusellers/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p>In the end, I spent more time than the old me would have liked understanding the library. But the reality of it is, this small investment in understanding a key part of my infrastructure is going to pay dividends in the long run. And less than a day understanding how a critical part of my system works, is indeed a small investment. So, from here on out I am going to remember. <strong>Patient / Fast</strong></p>
<div class="shr-publisher-274"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F04%2F22%2Fsunday-thought-patient-fast%2F' data-shr_title='Sunday+Thought%3A+Patient+%2F+Fast'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F04%2F22%2Fsunday-thought-patient-fast%2F' data-shr_title='Sunday+Thought%3A+Patient+%2F+Fast'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fdrusellers%2F2012%2F04%2F22%2Fsunday-thought-patient-fast%2F' data-shr_title='Sunday+Thought%3A+Patient+%2F+Fast'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/VYWHVOOFqTM" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/odBjyIohu0w" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/drusellers/2012/04/22/sunday-thought-patient-fast/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
					<feedburner:origLink>http://codebetter.com/drusellers/2012/04/22/sunday-thought-patient-fast/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/VYWHVOOFqTM/</feedburner:origLink></item>
	      
    	<item>
		<title>Ruby and RSpec: Powerful Languages Allow Simpler Frameworks</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/LrnSlGh25bw/</link>
		<comments>http://codebetter.com/jameskovacs/2012/04/19/ruby-and-rspec-powerful-languages-allow-simpler-frameworks/#comments</comments>
		<pubDate>Fri, 20 Apr 2012 04:32:51 +0000</pubDate>
		<dc:creator>James Kovacs</dc:creator>
				<category><![CDATA[Ruby]]></category>
			<guid isPermaLink="false">http://codebetter.com/jameskovacs/?p=209</guid>
					<description><![CDATA[Recently I was doing a simple kata &#8211; the Roman Numeral kata &#8211; to practice my Ruby and RSpec skills. (The Roman Numeral kata is to build an algorithm test-first that converts a number into its Roman numeral equivalent. For&#160;&#8230; <a href="http://codebetter.com/jameskovacs/2012/04/19/ruby-and-rspec-powerful-languages-allow-simpler-frameworks/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Recently I was doing a simple kata &#8211; <a href="http://codingdojo.org/cgi-bin/wiki.pl?KataRomanNumerals">the Roman Numeral kata</a> &#8211; to practice my Ruby and RSpec skills. (The Roman Numeral kata is to build an algorithm test-first that converts a number into its Roman numeral equivalent. For example, 1 to i, 7 to vii, 10 to x, etc. The problem is intended to be simple so that you can focus on the process.) I had the following RSpec code:</p>
<pre class="brush: ruby; title: ; notranslate">
require 'roman_numeral'

describe RomanNumeral do
  # specify is just an alias for it. specify reads better in this case
  specify '1 should be i' do
    numeral = RomanNumeral.new(1)
    numeral.to_s.should == 'i'
  end
end
</pre>
<p>I go through the Red/Green/Refactor cycle and get this first spec working. (I won&#8217;t show the production code as it&#8217;s not that interesting.) I move onto the second spec.</p>
<pre class="brush: ruby; title: ; notranslate">
require 'roman_numeral'

describe RomanNumeral do
  specify '1 should be i' do
    numeral = RomanNumeral.new(1)
    numeral.to_s.should == 'i'
  end

  specify '2 should be ii' do
    numeral = RomanNumeral.new(2)
    numeral.to_s.should == 'ii'
  end
end
</pre>
<p>Red/Green/Refactor and all is good. But I&#8217;m seeing some repetition in my specs and it&#8217;s only going to get worse. The specs are almost identical except for the data. So I start hunting through the RSpec docs for something akin to NUnit&#8217;s [TestCase] or xUnit&#8217;s [Theory]. I find nothing. Maybe, <a href="http://stackoverflow.com/questions/6121421/is-it-possible-to-create-data-driven-tests-with-mspec">like MSpec</a>, RSpec wasn&#8217;t designed to do this sort of data-driven testing.</p>
<p>Undaunted I turn to Google and stumble upon <a href="http://stackoverflow.com/questions/5524056/rspec-scenario-outlines-multiple-test-cases">this StackOverflow question</a> asking exactly the same question that I had. <a href="http://www.mattdipasquale.com/">Matt Di Pasquale</a>, the OP (original poster), found his own answer and that answer was fascinating! No, RSpec doesn&#8217;t have a syntax for test cases because it doesn&#8217;t need one. Use the Ruby, Luke!</p>
<pre class="brush: ruby; title: ; notranslate">
require 'roman_numeral'

describe RomanNumeral do
  cases = {
    1 =&gt; 'i',
    2 =&gt; 'ii'
  }

  cases.each do |k, v|
    specify &quot;#{k} should print as #{v}&quot; do
      numeral = RomanNumeral.new(k)
      numeral.to_s.should == v
    end
  end
end
</pre>
<p>For those not as well-versed in Ruby, &#8220;cases&#8221; is simply a variable that contains a hash. I then iterate over the key/value pairs and define my specifications. It&#8217;s that simple. I didn&#8217;t need any special attributes or framework support from RSpec. I didn&#8217;t need to learn the inner workings of RSpec to write my own custom extension or attributes. I simply wrote some Ruby code. Let that sink in for a second. <strong>I simply wrote some Ruby code.</strong></p>
<p>Now think about that a bit more. I&#8217;m writing regular Ruby code to implement the notion of test cases. Rather than defining test cases, I could have used very similar code to define a benchmark that verifies an algorithm scales linearly with number of input elements. Or I could have <a href="http://en.wikipedia.org/wiki/Fuzz_testing">fuzz tested</a> an external API for my application. The possibilities are only limited by my imagination and don&#8217;t require me to gain an ever deeper understanding of my testing/specing framework to implement.</p>
<p>For someone who cut his teeth on C, C++, and C# (with some JavaScript thrown in for good measure) and is used to learning (or building) frameworks to solve problems, the notion that you can just write plain old code to solve these types of meta problems is eye-opening. It is one of those ah-ha moments that matures you as a developer. Not every problem needs a framework to solve it. Sometimes it just requires a little code.</p>
<div class="shr-publisher-209"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjameskovacs%2F2012%2F04%2F19%2Fruby-and-rspec-powerful-languages-allow-simpler-frameworks%2F' data-shr_title='Ruby+and+RSpec%3A+Powerful+Languages+Allow+Simpler+Frameworks'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjameskovacs%2F2012%2F04%2F19%2Fruby-and-rspec-powerful-languages-allow-simpler-frameworks%2F' data-shr_title='Ruby+and+RSpec%3A+Powerful+Languages+Allow+Simpler+Frameworks'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjameskovacs%2F2012%2F04%2F19%2Fruby-and-rspec-powerful-languages-allow-simpler-frameworks%2F' data-shr_title='Ruby+and+RSpec%3A+Powerful+Languages+Allow+Simpler+Frameworks'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/prchq5r5S5I" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/LrnSlGh25bw" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/jameskovacs/2012/04/19/ruby-and-rspec-powerful-languages-allow-simpler-frameworks/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
					<feedburner:origLink>http://codebetter.com/jameskovacs/2012/04/19/ruby-and-rspec-powerful-languages-allow-simpler-frameworks/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/prchq5r5S5I/</feedburner:origLink></item>
	      
    	<item>
		<title>Using oData with the NuGet API</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/UgdZS8zfwn8/</link>
		<comments>http://codebetter.com/johnvpetersen/2012/04/15/using-odata-with-the-nuget-api/#comments</comments>
		<pubDate>Sun, 15 Apr 2012 16:49:49 +0000</pubDate>
		<dc:creator>johnvpetersen</dc:creator>
				<category><![CDATA[NuGet]]></category>
		<category><![CDATA[oData]]></category>
			<guid isPermaLink="false">http://codebetter.com/johnvpetersen/?p=436</guid>
					<description><![CDATA[Update&#8230; As a commenter astutely pointed out, we can see the generated URL in LinqPad.. Still good to know and understand how to use Fiddler &#8211; especially if you want to flip between json and xml formats!! &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; Quick tip&#160;&#8230; <a href="http://codebetter.com/johnvpetersen/2012/04/15/using-odata-with-the-nuget-api/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Update&#8230;</p>
<p>As a commenter astutely pointed out, we can see the generated URL in LinqPad..</p>
<p><a href="http://codebetter.com/johnvpetersen/files/2012/04/image10.png"><img src="http://codebetter.com/johnvpetersen/files/2012/04/image10-300x240.png" alt="" width="300" height="240" class="alignnone size-medium wp-image-464" /></a></p>
<p>Still good to know and understand how to use Fiddler &#8211; especially if you want to flip between json and xml formats!!</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p>Quick tip here on using <a href="http://www.odata.org/" target="_blank">oData</a> with <a href="http://www.nuget.org" target="_blank">NuGet</a>.</p>
<p>If you have visited the <a href="http://www.nuget.org" target="_blank">NuGet Gallery</a>, you may have wondered were the RSS feed is. Try as you might, you won&#8217;t find it. There&#8217;s good reason for that given the fact that NuGet is backed by a data feed &#8211; a data feed with many data fields that you can query to properly scope your request. NuGet has a rich API -which you will see in a moment. Usually, when we work with NuGet, we do so via the NuGet Package Manager Dialog and/or the Package Manager Console. There may be times when you wish the raw feed. To do that, you need the API url. By default, NuGet gives you one package source, the official public NuGet Feed &#8211; which can be found at <a href="https://nuget.org/api/v2" target="_blank">https://nuget.org/api/v2</a>. The following image illustrates how the official feed is wired into your NuGet installation. You can get to this dialog by navigating to:</p>
<p>Tools\Library Package Manager\Package Manger Settings</p>
<p><a href="http://codebetter.com/johnvpetersen/files/2012/04/image12.png"><img class="alignleft size-medium wp-image-440" src="http://codebetter.com/johnvpetersen/files/2012/04/image12-300x174.png" alt="" width="300" height="174" /></a></p>
<p>One of the most useful features in .NET is Linq and the best tool available to learn Linq is <a href="http://www.linqpad.net/" target="_blank">LinqPad</a>. In the following image, I set a connection to https://nuget.org/api/v2. As you can see, there are a number of fields in the package feed. With LinqPad, it&#8217;s easy to enter a Linq Query (whether it is the long form or as a lambda expression).</p>
<pre><a href="http://codebetter.com/johnvpetersen/files/2012/04/image22.png"><img class="alignnone size-medium wp-image-441" src="http://codebetter.com/johnvpetersen/files/2012/04/image22-300x240.png" alt="" width="300" height="240" /></a>
<pre class="brush: csharp; title: ; notranslate">
Packages.OrderByDescending (x =&gt; x.LastUpdated)
   .Select (
	  x =&gt;
		 new
		 {
			Id = x.Id,
			Tags = x.Tags,
			Title = x.Title,
			Description = x.Description,
			ProjectUrl = x.ProjectUrl,
			GalleryDetailsUrl = x.GalleryDetailsUrl,
			Version = x.Version,
			LastUpdated = x.LastUpdated
		 }
   )
</pre>
<p>In this query, we are taking certain data fields and are ordering by the LastUpdated DateTime field descending.</p>
<p>Another useful tool is fiddler. The combination of LinqPad and Fiddler makes it easy to see how Linq queries get translated to oData URL's:</p>
<p><a href="http://codebetter.com/johnvpetersen/files/2012/04/image31.png"><img class="alignnone size-medium wp-image-442" src="http://codebetter.com/johnvpetersen/files/2012/04/image31-300x183.png" alt="" width="300" height="183" /></a></p>
<p>Here's how the oData URL appears as rendered in a browser:</p>
<p><a href="http://codebetter.com/johnvpetersen/files/2012/04/image42.png"><img class="alignnone size-medium wp-image-443" src="http://codebetter.com/johnvpetersen/files/2012/04/image42-300x163.png" alt="" width="300" height="163" /></a></p>
<p>Here is the URL:</p>
<p><a href="http://nuget.org/api/v2/Packages()?$orderby=LastUpdated%20desc&amp;$select=Id,Tags,Title,Description,ProjectUrl,GalleryDetailsUrl,Version,LastUpdated">http://nuget.org/api/v2/Packages()?$orderby=LastUpdated%20desc&amp;$select=Id,Tags,Title,Description,ProjectUrl,GalleryDetailsUrl,Version,LastUpdated</a></p>
<p>Going back to Fiddler, if you want JSON returned instead of XML, just tweak the Accept Header to:</p>
<p>Accept: application/atom+json,application/json</p>
<p><a href="http://codebetter.com/johnvpetersen/files/2012/04/image5.png"><img class="alignnone size-medium wp-image-444" src="http://codebetter.com/johnvpetersen/files/2012/04/image5-300x183.png" alt="" width="300" height="183" /></a></p>
<p>That's all there is to accessing NuGet data via the NuGet API with oData.</p>
<div class="shr-publisher-436"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F15%2Fusing-odata-with-the-nuget-api%2F' data-shr_title='Using+oData+with+the+NuGet+API'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F15%2Fusing-odata-with-the-nuget-api%2F' data-shr_title='Using+oData+with+the+NuGet+API'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F15%2Fusing-odata-with-the-nuget-api%2F' data-shr_title='Using+oData+with+the+NuGet+API'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/ZCwXIkL0iKU" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/UgdZS8zfwn8" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/johnvpetersen/2012/04/15/using-odata-with-the-nuget-api/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
					<feedburner:origLink>http://codebetter.com/johnvpetersen/2012/04/15/using-odata-with-the-nuget-api/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/ZCwXIkL0iKU/</feedburner:origLink></item>
	      
    	<item>
		<title>Why I’m moving away from Apple, and specifically, the iPhone and going to the store</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/nrvlWKMA3eg/</link>
		<comments>http://codebetter.com/johnvpetersen/2012/04/14/why-im-moving-away-from-apple-and-specifically-the-iphone-and-going-to-the-store/#comments</comments>
		<pubDate>Sat, 14 Apr 2012 20:52:51 +0000</pubDate>
		<dc:creator>johnvpetersen</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[Apple Store King of Prussia]]></category>
		<category><![CDATA[iPhone]]></category>
			<guid isPermaLink="false">http://codebetter.com/johnvpetersen/?p=430</guid>
					<description><![CDATA[And it has nothing to do with technology for the most part. On balance, Apple makes some great products. But there are two things that Apple sucks at: - Customer Service (especially at an Apple Store &#8211; more on this&#160;&#8230; <a href="http://codebetter.com/johnvpetersen/2012/04/14/why-im-moving-away-from-apple-and-specifically-the-iphone-and-going-to-the-store/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>And it has nothing to do with technology for the most part. On balance, Apple makes some great products. But there are two things that Apple sucks at:</p>
<p>- Customer Service (especially at an Apple Store &#8211; more on this later)<br />
- Battery life</p>
<p>First off, I&#8217;d like to thank Luke C., one of the managers at the King of Prussia Apple Store for wasting 90 min of my life today. The same goes for the other manager of whom I didn&#8217;t get his name.</p>
<p>I have said this every time I&#8217;ve gone into an Apple Store lately&#8230;.&#8221;Never again.&#8221; They are crowded and unless you are there to buy something, the Apple retail crew is not really interested in helping you. The tough thing with batteries is that you have to go through some difficulty to get issues addressed. That often means going to the store &#8211; and make an appointment at the &#8220;Genius Bar.&#8221; Don&#8217;t know about you, but when I pay premium prices for a product, I expect superior customer service. And more often than not, I usually get it. Tumi is a great example of a company that stands behind their products.</p>
<p>Anyway, for some time now, I&#8217;ve had issues with battery life wtih my iPhone. I had the phone replace in December &#8211; and for the most part &#8211; it&#8217;s been OK. Today, Luke C. stated that they had their process. They had to make sure it wasn&#8217;t a software related problem. I was agreeable. Fast forward 50 minutes and while they told me everything was OK &#8211; turns out that it wasn&#8217;t. The battery drains at a rate of about 1% every 2-3 min. The funny thing is, when confronted wtih an outcome he didn&#8217;t expect, Luke and his buddy stated &#8211; &#8220;I could buy a new battery for $89.&#8221; I then became disagreeable. What is it with these folks that work at the Apple Stores? Is it a requirement to be a pendantic d-bag? They clearly have lying down to a fine art. Whatever &#8211; I have to consider the source. These guys work in retail and are a reminder why I prefer the online experience when it comes to making purchases.</p>
<p>Often, when considering things like phones, tablets, etc &#8211; we evaluate based on technology. We really should be looking at customer service as well. And in the case of Apple, that charges a premium price for their products &#8211; they have a greater responsibility to provide superior customer service. The irony as to the store is that for all of the &#8220;experience&#8221; the Apple folks worry about, an Apple store today, has got to be the worse customer experience out there today. Others may disagree &#8211; but that is my opinion.</p>
<p>I&#8217;m just one guy and Apple won&#8217;t care as it&#8217;s market cap continues to creep toward a trillion dollars. <a href="http://www.pcmag.com/article2/0,2817,2400611,00.asp" target="_blank">Apple makes a profit of over $350 per iPhone and it is hypothesized that Apple generates $30 of profit on an iPhone for every $1 of labor</a>. And the $89 battery? What&#8217;s that cost? $5&#8230;maybe. </p>
<p>I&#8217;m all for companies making as much as they can. I&#8217;m a capitalist. But&#8230;I&#8217;m also a &#8220;fairist&#8221; as well. In other words, I believe that companies should earn the premium they charge. Standing behind their products, when they are defective, is such a case when they need to earn that premium. Well&#8230;I have my remedy as well. </p>
<div class="shr-publisher-430"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F14%2Fwhy-im-moving-away-from-apple-and-specifically-the-iphone-and-going-to-the-store%2F' data-shr_title='Why+I%27m+moving+away+from+Apple%2C+and+specifically%2C+the+iPhone+and+going+to+the+store'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F14%2Fwhy-im-moving-away-from-apple-and-specifically-the-iphone-and-going-to-the-store%2F' data-shr_title='Why+I%27m+moving+away+from+Apple%2C+and+specifically%2C+the+iPhone+and+going+to+the+store'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F14%2Fwhy-im-moving-away-from-apple-and-specifically-the-iphone-and-going-to-the-store%2F' data-shr_title='Why+I%27m+moving+away+from+Apple%2C+and+specifically%2C+the+iPhone+and+going+to+the+store'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/FXseYLQKeao" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/nrvlWKMA3eg" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/johnvpetersen/2012/04/14/why-im-moving-away-from-apple-and-specifically-the-iphone-and-going-to-the-store/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
					<feedburner:origLink>http://codebetter.com/johnvpetersen/2012/04/14/why-im-moving-away-from-apple-and-specifically-the-iphone-and-going-to-the-store/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/FXseYLQKeao/</feedburner:origLink></item>
	      
    	<item>
		<title>Audit Fields in Google AppEngine</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/l7dL4KT2atw/</link>
		<comments>http://codebetter.com/kylebaley/2012/04/07/audit-fields-in-google-appengine/#comments</comments>
		<pubDate>Sat, 07 Apr 2012 23:52:41 +0000</pubDate>
		<dc:creator>Kyle Baley</dc:creator>
				<category><![CDATA[Google App Engine]]></category>
			<guid isPermaLink="false">http://codebetter.com/kylebaley/?p=275</guid>
					<description><![CDATA[Executive summary: Here’s how we’re implementing audit fields in AppEngine. IT’S BETTER THAN THE WAY YOU’RE DOING IT! I considered saying “I hope there’s a better way of doing it” but I believe I’ll get more responses if I frame&#160;&#8230; <a href="http://codebetter.com/kylebaley/2012/04/07/audit-fields-in-google-appengine/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>Executive summary: Here’s how we’re implementing audit fields in AppEngine. IT’S BETTER THAN THE WAY YOU’RE DOING IT!</p>
<p>I considered saying “I hope there’s a better way of doing it” but I believe I’ll get more responses if I frame it in the form of a challenge.</p>
<p>For all entities in our datastore, we want to store:</p>
<ul>
<li>dateCreated
<li>dateModified
<li>dateDeleted
<li>createdByUser
<li>modifiedByUser
<li>deletedByUser</li>
</ul>
<p>Here are the options we’ve considered</p>
<h2>Datastore callbacks/Lifecycle callbacks</h2>
<p><img style="border-right-width: 0px;padding-left: 0px;padding-right: 0px;float: right;border-top-width: 0px;border-bottom-width: 0px;border-left-width: 0px;padding-top: 0px" border="0" alt="Audit" align="right" src="http://codebetter.com/kylebaley/files/2012/04/Audit.png" width="240" height="159">AppEngine supports <a href="https://developers.google.com/appengine/docs/java/datastore/callbacks">datastore callbacks</a> natively. If you use Objectify, they have <a href="http://code.google.com/p/objectify-appengine/wiki/IntroductionToObjectify#Lifecycle_Callbacks">lifecycle callbacks</a> for @PrePersist and @PostLoad. The former works fantastic for dateCreated, dateModified, and dateDeleted. Objectify can handle all three easily as well provided you use soft deletes, which we do. (And they <a href="http://weblogs.asp.net/fbouma/archive/2009/02/19/soft-deletes-are-bad-m-kay.aspx">aren’t as bad</a> as <a href="http://ayende.com/blog/4157/avoid-soft-deletes">people would have you believe</a>, especially in AppEngine. You’d be surprised how many user experience problems you discover strolling through deleted data.)</p>
<p>Both of these led to problems for us when we tried to use them for the createdByUser et al methods. We store the current user in the session and access it through a UserRetrievalService (which, at its core, just retrieves the current HttpSession via a Guice provider).</p>
<p>If we want to use this with the Objectify lifecycle callbacks, we would need to inject either our UserRetrievalService or a Provider&lt;HttpSession&gt; into our domain entities. This isn’t something I’m keen on doing so we didn’t pursue this too rigorously.</p>
<p>The datastore callbacks have an advantage in that they can be stored completely separately from the entities and the repositories. But we ran into two issues.</p>
<p>First, we couldn’t inject anything into them, either via constructor injection or static injection. It looks like there’s something funky about how they hook into the process that I don’t understand and my guess is that they are instantiated explicitly somewhere along the line. Regardless, it meant we couldn’t inject our UserRetrievalService or a Provider&lt;HttpSession&gt; into the class.</p>
<p>The next issue was automating the build. When I try to compile the project with a callback in it, the javac task complained about a missing datastorecallbacks.xml file. This file gets created when you build the project in Eclipse but something about how I was doing it via ant obviously wasn’t right. This also leads me to believe there’s something going on behind the scenes.<img style="margin: 5px;float: left" align="left" src="http://rlv.zcache.com/auditing_it_is_tshirt-p235602047235350805z8npz_400.jpg" width="400" height="400"></p>
<p>Neither of these problems is unsurmountable, I don’t think. There is obviously some way of accessing the current HttpSession somehow because Guice is doing it. And clearly you can compile the application when there’s a callback because Eclipse does it. All the same, both issues remaining unsolved by us, which is a shame because I kind of like this option.</p>
<h2>Pass the User to Repository</h2>
<p>This is what was suggested in the <a href="http://stackoverflow.com/questions/9952538/audit-fields-for-appengine-entities">StackOverflow question</a> I posed on the topic. We have repositories for most of our entities so instead of calling put( appointment ), we’d call put( appointment, userWhoPerformedTheAction ).</p>
<p>&nbsp;</p>
<p>I don’t know that I like this solution (as indicated in my comments). To me, passing the current user into the DAO/Repository layer isn’t something the caller should have to worry about. But that’s because in my .NET/NHibernate/SQL Server experience, you can set things up so you don’t have to. Maybe it’s common practice in AppEngine because it’s still relatively new.</p>
<p>(Side note: This question illustrates a number of reasons why I don’t like asking questions on StackOverflow. I usually put a lot of effort into phrasing the question and people often still end up misunderstanding the goal I’m trying to achieve. Which is my fault more than theirs but still means I tend to shy away from SO as a result.)</p>
<h2>Add a User property to each Entity</h2>
<p>I can’t remember where I saw this suggestion. It’s kind of the opposite of the previous one. Each entity would have a User property (marked as @Transient) and when the object is loaded, this is set to the current user. Then in your repositories, it’s trivial to set the user who modified or deleted. This has the same issue I brought up with the last one in that the caller is responsible for setting the User object.</p>
<p>Also, when new objects are created, we’d need to set the property there as well. If you’re doing this on the client, you may have some issues there since you won’t have access to the HttpSession until you send it off to the server.</p>
<h2>Do it yourself</h2>
<p>This is our current implementation. In our repositories, we have a prePersist method that is called before the actual “save this to the datastore” method. Each individual repository can override this as necessary. The UserRetrievalService is injected in and we can use it to set the relevant audit fields before saving to the repository.</p>
<p>This works just fine for us and we’ve extended it to perform other domain-specific prePersist actions for certain entities. I’m not entirely happy with it though. Our repositories tend not to favour composition over inheritance and as such, it is easy to forget to make a call to super.prePersist somewhere along the way. Plus there’s the nagging feeling that it should be cleaner and more testable than this.</p>
<p>Related to this is the underlying problem we’re trying to solve: retrieve the user from the session. In AppEngine, the session is really just the datastore (and memcache) with a fancy HttpSession wrapper around it. So when you get the current user from the session, you’re really just getting it from the datastore anyway using a session ID that is passed back and forth from the client. So if we *really* wanted to roll our own here, we’d implement our own session management which would be more easily accessible from our repositories.</p>
<p>So if you’re an AppEngine user, now’s where you speak up and describe if you went with one of these options or something else. Because this is one of the few areas of our app that fall under the category of “It works but…” And I don’t think it should be.</p>
<p>Kyle the Pre-persistent</p>
<div class="shr-publisher-275"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F07%2Faudit-fields-in-google-appengine%2F' data-shr_title='Audit+Fields+in+Google+AppEngine'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F07%2Faudit-fields-in-google-appengine%2F' data-shr_title='Audit+Fields+in+Google+AppEngine'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fkylebaley%2F2012%2F04%2F07%2Faudit-fields-in-google-appengine%2F' data-shr_title='Audit+Fields+in+Google+AppEngine'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/712B9ldEi0c" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/l7dL4KT2atw" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/kylebaley/2012/04/07/audit-fields-in-google-appengine/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
					<feedburner:origLink>http://codebetter.com/kylebaley/2012/04/07/audit-fields-in-google-appengine/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/712B9ldEi0c/</feedburner:origLink></item>
	      
    	<item>
		<title>Microsoft and Open Source</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/HAvX6ryoBj8/</link>
		<comments>http://codebetter.com/sebastienlambla/2012/04/05/microsoft-and-open-source-2/#comments</comments>
		<pubDate>Thu, 05 Apr 2012 11:44:09 +0000</pubDate>
		<dc:creator>Sebastien Lambla</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
			<guid isPermaLink="false">http://codebetter.com/sebastienlambla/?p=143</guid>
					<description><![CDATA[I have been a vocal, and sometimes harsh, critic of Microsoft’s approach to Open Source Software. I call that activism, some call it whining, ranting or pisser dans la soupe. People are entitled to their opinion, and mine has been&#160;&#8230; <a href="http://codebetter.com/sebastienlambla/2012/04/05/microsoft-and-open-source-2/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>I have been a vocal, and sometimes harsh, critic of Microsoft’s approach to Open Source Software. I call that activism, some call it whining, ranting or <em>pisser dans la soupe.</em> People are entitled to their opinion, and mine has been formed after working in the Microsoft sphere for more or less 14 years.</p>
<p>Over the years, the various component organizations within Microsoft have had various levels of involvement with Open Source, with different philosophies, and from what I have gathered over the years from post-conference drinks, internal conflicts that can be quite a challenge.</p>
<p>As this post is going to be long, I’m going to sum-up the problem, and you can go to the conclusion bit to read what I believe should be done differently.</p>
<p>Microsoft has no <em>vision</em> when it comes to Open-Source, no strategy and no leadership. Some groups are seen as more progressive, and do tend towards a better approach to OSS. Some people consider those steps as sufficient to stop pressuring Microsoft towards responsible OSS, and I disagree: it’s only some groups, and even within those groups, the advances are still very much one of exporter. Recognizing Microsoft as an OSS-friendly player is like recognizing the People’s Republic of China under the Reagan administration, it’s a step in the direction of normalization, not a recognition of the Human Right lifetime achievements of Mao Tsedung.</p>
<p><a href="http://codebetter.com/sebastienlambla/files/2012/04/Untitled6.jpg"><img style="margin: 0px 0px 24px;padding-left: 0px;padding-right: 0px;float: right;padding-top: 0px;border-width: 0px" src="http://codebetter.com/sebastienlambla/files/2012/04/Untitled6_thumb.jpg" alt="Untitled6" width="244" height="157" align="right" border="0" /></a>You know why I <strong>know</strong> Microsoft has no leadership and vision when it comes to Open-Source? Because I asked Steve Ballmer when he was in London, and he replied with this: “I don’t know, but we won’t impose any view on our divisions. I’ll come back to you by email though.” Steve, my email is still <a href="mailto:seb@serialseb.com">seb@serialseb.com</a> and I’m looking forward to your views.</p>
<h2>Where we come from</h2>
<p>The current state of affairs is not bad, considering where Microsoft was years ago. We’re talking about a company that positioned itself as the defender of private code, vilifying OSS licenses, having no visible OSS project going and providing its value as the integrated stack: it’s all MS or none. We have certainly come a long way.</p>
<h2>Opening up slowly</h2>
<p>I think under the influence of Scott Guthrie, an internal change started deep within the asp.net team ranks, certainly a movement that resulted in the recent announcement of the opening up of the asp.net webstack as a true Open-Source project.</p>
<p>Now <strong>that’s </strong>commendable, and I applaud the move. Open-Sourcing and opening up to collaborative development for stuff you’ve built is great. Well done.</p>
<h2>Not invented in Redmond syndrome</h2>
<p>Let’s be clear. The goal of MVC was to build a better Monorail, as opposed to help Monorail productize their framework for inclusion in Visual Studio.</p>
<p>The exact same thing happened with Nuget. With multiple projects with different approaches already in the work, Microsoft started their NPack project (I seem to recall someone at Oredev mentioning it was originally built as part of the WebPages tooling). It wasn’t to be open-source to start with, hence why the existing OSS projects didn’t get the news until much later.</p>
<p>But, I hear you say, Nuget is an open-source project from Outercurve, and they combined their code with another project. The open-sourcing was decided very late in that process, once the investment in code was so large that the ship had left already and nothing would stop it. And on a side-note, there was no merging of the code, the Outercurve foundation’s press release was inaccurate, just look at the history.</p>
<p>What really happens when a new project gets produced by Microsoft? It sucks the air out of a lot of community projects, often including all the best ideas of said projects, and Microsoft gives nothing back. If you’re in that boat, you either redraw your plans based on their new announcements (usually rewriting on top of the new shiny stuff), or you dissolve your group and join their OSS project (the Nuget / Nubular case).</p>
<p>Certain projects (like nhibernate and nunit) continue to happily go forward, and maybe the OSS alternatives that are impacted by Microsoft entering a space just were not good enough. I don’t know, we’ll see in a few years.</p>
<h2>Adoption of existing projects</h2>
<p>Of course it can be said, and there again, I commend Microsoft for the move, that libraries such as jQuery, modernizr and now Newtonsoft.Json, are being used, supported by Microsoft and shipped alongside the product.</p>
<p>This is also a great departure from time immemorials. Makes no mistake however, Microsoft is being pushed by market pressure to integrate with those frameworks. The change is only that they’re abandoning slowly the idea that they’ll release until they gain marketshare, in those domains where Microsoft has historically been slow at releasing compared to alternative platforms.</p>
<p>This is only an opinion piece, but I’ll suggest that the move to gain web development share has pushed Microsoft towards dropping the projects they had and failed to make popular (the asp.net  AJAX stuff that got more or less killed when jQuery was adopted). And I think that’s great.</p>
<p>Pragmatism is also the reason why newtonsoft.json is being used by Web API. The current Json providers on .net are broken, there is no way to provide the customization people want, and fixing them cannot be done in the same release cycles as MVC, as some are part of the core framework (and may or may never be fixed, but certainly not in time for the next release).</p>
<p>It was not chosen because Microsoft wants to adopt more external OSS projects as their core vision. It was chosen because they couldn’t fix what was broken and rebuilding would have been silly.</p>
<p><em>On a side-note, twitter conversations started going in the direction of why Newtonsoft.Json was chosen over other libraries. I made the assertion that provided it’s an internal implementation with no exposed surface, the choice of *any* json lib would’ve been fine. ScottHa said it was because the library was the most popular, and testing was done on their part. That lead me to the assertion that if the only library under consideration was chosen for popularity, <strong>and</strong> there is no exposed surface of that lib on public APIs, the choice is one of brand-surfing and gives extra marketing points to their OSS credentials. If some of the API is exposed, it was probably a reasonable choice. I don’t care which library you chose, I care the process you used to chose which library and the reasoning behind it. I question (and by question, I mean discuss) the motives, not the solution.</em></p>
<p><em>[Edit: After looking for it (as the twiterverse didn’t reply to the specific of the discussion), one object from json.net *is* exposed on the <a href="http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/55f7dc693838#src%2fSystem.Net.Http.Formatting%2fFormatting%2fJsonMediaTypeFormatter.cs">JsonMediaTypeFormatter</a>, so that is that and I’ll stick to my original analysis, it’s probably a reasonable choice.]</em></p>
<p>There is no vision, because there is no systemic approach to deciding between building and joining communities.</p>
<p>Asp.net Web API could have quite happily join existing OSS projects that dealt with this problem area years ago, but it wasn’t to be. Nuget funding could have been used on top of existing projects, instead of a pure creation, but it wasn’t to be either. What is the decision process behind the rebuild or join decision?</p>
<p>And can anyone that has had their project get the oxygen sucked out of, with nothing given back, be blamed for distrusting the company?</p>
<h2><a href="http://codebetter.com/sebastienlambla/files/2012/04/220px-Borg_Queen_2372.jpg"><img style="margin: 0px 0px 24px;padding-left: 0px;padding-right: 0px;float: right;padding-top: 0px;border-width: 0px" src="http://codebetter.com/sebastienlambla/files/2012/04/220px-Borg_Queen_2372_thumb.jpg" alt="220px-Borg_Queen_2372" width="129" height="158" align="right" border="0" /></a>The corporation</h2>
<p>When the Web API project was being kicked off, <a href="http://codebetter.com/glennblock/">Glenn Block</a> called me asking me if I thought he should take the job, and if he did, would I help. I told him what I’m telling you now: Yes, you can’t do as bad as the previous attempts, and I’ll happily help to make sure the architecture and model fits the reality of what developers want, we’ll all win. I helped because I was asked. Ideally I’d rather they had asked me to work on OpenRasta and create a new version with us, but it was not to be. In the end, the two frameworks may have very different code, but most of the concepts and conventions are exactly the same, so everyone will feel right at home on both platforms, and that’s in no small measure because the brilliant minds behind Web API respected HTTP as much as I and the other advisors did.</p>
<p>More recently, <a href="http://www.twitter.com/anglicangeek">Drew Miller</a> from the NuGet team has been very active in opening communication channels with OpenWrap, something that has not existed ever, and he should be applauded for it: I can now have a discussion about our interop story with someone that wants to make things better. Again, I’d rather the NuGet team had joined OpenWrap rather than communicate to us their imminent release, way too late to get any positive outcome, but at least it’s a step in the right direction.</p>
<p>Those are individuals, not the company, and out of all the voices out there, they are a minority. You cannot judge the whole company on specific individuals, and teams cannot use the excuse <em>Microsoft is really many companies</em>. That is certainly true, but completely irrelevant to external agents when judging how the company deals with OSS.</p>
<h2><a href="http://codebetter.com/sebastienlambla/files/2012/04/transparency.jpg"><img style="margin: 0px 0px 24px;padding-left: 0px;padding-right: 0px;float: right;padding-top: 0px;border-width: 0px" src="http://codebetter.com/sebastienlambla/files/2012/04/transparency_thumb.jpg" alt="transparency" width="217" height="320" align="right" border="0" /></a>How to fix this</h2>
<p>Three words, transparency, transparency, transparency.</p>
<p>When you have an idea for a product, and there are existing Open-Source projects out there that have adoption and could really help the resources of a big vendor, try and justify the choice.</p>
<p>If you’re going to rebuild, take the phone, call the leader, explain your plans, and don’t be a douche about it (aka telling someone “we realize we are stepping on toes here but we’re big so it’ll happen” is not particularly a great way to deliver the news). Chances are, they’ll probably understand the reasoning. ISVs have had <a href="http://www.ericsink.com/item_10169.html">that communication channel from Microsoft for years</a>, and get to know about competing products way in advance, but it’s not the case for OSS projects.</p>
<p>Be open about the process afterwards too. The policy of not mentioning anyone, or pretending you cannot look at existing projects at all in public, would make anyone think you have something to hide. It probably is against some corporate policy somewhere, but make that change, you did do it about the no-OSS policy.</p>
<p>And finally, value the people on your platform, the loud mouths like me and the small guys that abandon their projects because you started yours. We are on your platform because we like it, and we want to make it better. And maybe if you’re going to step on people’s toes, try to find a band aid for them to sweeten the blow, and find a way to collaborate on something else with them. Don’t lose the people that have been developing the ideas you’re going to be building on, it’s not good business.</p>
<p>If these things had happened in the last few years, I wouldn’t distrust Microsoft-the-company as much as I do now. But the bridges that are being built by bright individuals inside the company do go in the right direction.</p>
<p>Is that going to be enough? I sincerely don’t know, but until we’re there, I’ll continue shouting at the top of my voice for Microsoft to become the business partner my OSS projects wants to be dealing with.</p>
<p>It’s called tough love, silly.</p>
<p><em>[Edit: added an additional paragraph to project competition]</em></p>
<p><em>[Edit 2: added a bit on the json.net choice]</em></p>
<div class="shr-publisher-143"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fsebastienlambla%2F2012%2F04%2F05%2Fmicrosoft-and-open-source-2%2F' data-shr_title='Microsoft+and+Open+Source'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fsebastienlambla%2F2012%2F04%2F05%2Fmicrosoft-and-open-source-2%2F' data-shr_title='Microsoft+and+Open+Source'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fsebastienlambla%2F2012%2F04%2F05%2Fmicrosoft-and-open-source-2%2F' data-shr_title='Microsoft+and+Open+Source'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/Gi-3a1qqsVg" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/HAvX6ryoBj8" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/sebastienlambla/2012/04/05/microsoft-and-open-source-2/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
					<feedburner:origLink>http://codebetter.com/sebastienlambla/2012/04/05/microsoft-and-open-source-2/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/Gi-3a1qqsVg/</feedburner:origLink></item>
	      
    	<item>
		<title>Moving from Action Filters to Message Handlers</title>
		<link>http://feedproxy.google.com/~r/MatthewPodwysocki/~3/-MoSoucEPHo/</link>
		<comments>http://codebetter.com/johnvpetersen/2012/04/04/moving-from-action-filters-to-message-handlers/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 12:57:05 +0000</pubDate>
		<dc:creator>johnvpetersen</dc:creator>
				<category><![CDATA[ASP.NET MVC 4]]></category>
		<category><![CDATA[ASP.NET Web API]]></category>
			<guid isPermaLink="false">http://codebetter.com/johnvpetersen/?p=414</guid>
					<description><![CDATA[The updated code for the Web API project can be found here In the last post on Making Your ASP.NET Web API&#8217;s Secure, I received some very useful comments. Thanks to Pedro Reys for pointing out my non-use of HttpMessageHandlers.&#160;&#8230; <a href="http://codebetter.com/johnvpetersen/2012/04/04/moving-from-action-filters-to-message-handlers/">Continue&#160;reading&#160;<span class="meta-nav">&#8594;</span></a>]]></description>
							<content:encoded><![CDATA[<!-- Start Shareaholic LikeButtonSetTop Automatic --><!-- End Shareaholic LikeButtonSetTop Automatic --><p>The updated code for the Web API project can be found <a href="https://docs.google.com/open?id=0B6Zn8tqUVSf1MFBzcElyNVJUdG02NWtjSmMyR1Mydw" target="_blank">here</a> In the last post on <a title="Making your ASP.NET Web API’s secure" href="http://codebetter.com/johnvpetersen/2012/04/02/making-your-asp-net-web-apis-secure/" target="_blank">Making Your ASP.NET Web API&#8217;s Secure</a>, I received some very useful comments. Thanks to Pedro Reys for pointing out my non-use of HttpMessageHandlers. Pedro is absolutely correct in his observation that through the use of handlers, we can detect issues BEFORE processing gets into the controller context. If you are concerned about performance (and we all should be!!) &#8211; Http Message Handling is where you want to be. It turned out to be a pretty easier conversion. As you may recall, there were 3 actions filters that enforced:</p>
<ol>
<li>HTTPS</li>
<li>A valid authorization token</li>
<li>A valid IP Host source</li>
</ol>
<p>Here are the 3 new handlers:</p>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace WebAPI
{
 public class HttpsHandler : DelegatingHandler
 {
  protected override Task SendAsync(HttpRequestMessage request,
   CancellationToken cancellationToken)
  {
   if (!String.Equals(request.RequestUri.Scheme, &quot;https&quot;, StringComparison.OrdinalIgnoreCase))
   {
    return Task.Factory.StartNew(() =&gt;
    {
     return new HttpResponseMessage(HttpStatusCode.BadRequest)
     {
      Content = new StringContent(&quot;HTTPS Required&quot;)
     };
    });
   }
   return base.SendAsync(request, cancellationToken);
  }
 }
}
</pre>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using WebAPI.Models;

namespace WebAPI
{
 public class TokenValidationHandler : DelegatingHandler
 {
  protected override Task SendAsync(HttpRequestMessage request,
   CancellationToken cancellationToken)
  {
   string token;

   try
   {
    token = request.Headers.GetValues(&quot;Authorization-Token&quot;).FirstOrDefault();
   }
   catch (System.InvalidOperationException)
   {
    return Task.Factory.StartNew(() =&gt;
    {
     return new HttpResponseMessage(HttpStatusCode.BadRequest)
     {
      Content = new StringContent(&quot;Missing Authorization-Token&quot;)
     };
    });
   }

   try
   {
    var foundUser = AuthorizedUserRepository.GetUsers().FirstOrDefault(x =&gt; x.Name == RSAClass.Decrypt(token));
    if (foundUser == null)
     return Task.Factory.StartNew(() =&gt;
     {
      return new HttpResponseMessage(HttpStatusCode.Forbidden)
      {
       Content = new StringContent(&quot;Unauthorized User&quot;)
      };
     });
   }
   catch (RSAClass.RSAException)
   {
    return Task.Factory.StartNew(() =&gt;
    {
     return new HttpResponseMessage(HttpStatusCode.InternalServerError)
     {
      Content = new StringContent(&quot;Error encountered while attempting to process authorization token&quot;)
     };
    });
   }
   return base.SendAsync(request, cancellationToken);
  }
 }
}
</pre>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using WebAPI.Models;

namespace WebAPI
{
 public class IPHostValidationHandler : DelegatingHandler
 {
   protected override Task SendAsync(HttpRequestMessage request,
   CancellationToken cancellationToken) {

    var context = request.Properties[&quot;MS_HttpContext&quot;] as System.Web.HttpContextBase;
    string userIP = context.Request.UserHostAddress;

    var foundIP = AuthorizedIPRepository.GetAuthorizedIPs().FirstOrDefault(x =&gt; x == userIP);
    if (foundIP == null)
     return Task.Factory.StartNew(() =&gt;
     {
      return new HttpResponseMessage(HttpStatusCode.Forbidden)
      {
       Content = new StringContent(&quot;Unauthorized IP Address&quot;)
      };
     });

    return base.SendAsync(request, cancellationToken);

   }
 }
}
</pre>
<p>I went ahead and created a specific exception to address situations when the RSA encryption/description process throws the generic bad data exception. Here is the revised RSAClass:</p>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace WebAPI
{
 public class RSAClass
 {
  private static string _privateKey = &quot;s6lpjspk+3o2GOK5TM7JySARhhxE5gB96e9XLSSRuWY2W9F951MfistKRzVtg0cjJTdSk5mnWAVHLfKOEqp8PszpJx9z4IaRCwQ937KJmn2/2VyjcUsCsor+fdbIHOiJpaxBlsuI9N++4MgF/jb0tOVudiUutDqqDut7rhrB/oc=AQAB&lt;/pre&gt;
3J2+VWMVWcuLjjnLULe5TmSN7ts0n/TPJqe+bg9avuewu1rDsz+OBfP66/+rpYMs5+JolDceZSiOT+ACW2Neuw==
&lt;pre&gt;&lt;q&gt;0HogL5BnWjj9BlfpILQt8ajJnBHYrCiPaJ4npghdD5n/JYV8BNOiOP1T7u1xmvtr2U4mMObE17rZjNOTa1rQpQ==&lt;/q&gt;jbXh2dVQlKJznUMwf0PUiy96IDC8R/cnzQu4/ddtEe2fj2lJBe3QG7DRwCA1sJZnFPhQ9svFAXOgnlwlB3D4Gw==evrP6b8BeNONTySkvUoMoDW1WH+elVAH6OsC8IqWexGY1YV8t0wwsfWegZ9IGOifojzbgpVfIPN0SgK1P+r+kQ==LeEoFGI+IOY/J+9SjCPKAKduP280epOTeSKxs115gW1b9CP4glavkUcfQTzkTPe2t21kl1OrnvXEe5Wrzkk8rA==HD0rn0sGtlROPnkcgQsbwmYs+vRki/ZV1DhPboQJ96cuMh5qeLqjAZDUev7V2MWMq6PXceW73OTvfDRcymhLoNvobE4Ekiwc87+TwzS3811mOmt5DJya9SliqU/ro+iEicjO4v3nC+HujdpDh9CVXfUAWebKnd7Vo5p6LwC9nIk=&quot;;
  private static string _publicKey = &quot;s6lpjspk+3o2GOK5TM7JySARhhxE5gB96e9XLSSRuWY2W9F951MfistKRzVtg0cjJTdSk5mnWAVHLfKOEqp8PszpJx9z4IaRCwQ937KJmn2/2VyjcUsCsor+fdbIHOiJpaxBlsuI9N++4MgF/jb0tOVudiUutDqqDut7rhrB/oc=AQAB&quot;;
  private static UnicodeEncoding _encoder = new UnicodeEncoding();

  public static string Decrypt(string data)
  {

   try
   {
    var rsa = new RSACryptoServiceProvider();
    var dataArray = data.Split(new char[] { ',' });

    byte[] dataByte = new byte[dataArray.Length];
    for (int i = 0; i &lt; dataArray.Length; i++)
    {
     dataByte[i] = Convert.ToByte(dataArray[i]);
    }

    rsa.FromXmlString(_privateKey);
    var decryptedByte = rsa.Decrypt(dataByte, false);
    return _encoder.GetString(decryptedByte);

   }
   catch (Exception)
   {
    throw new RSAException();
   }

  }

  public static string Encrypt(string data)
  {

   try
   {
    var rsa = new RSACryptoServiceProvider();
    rsa.FromXmlString(_publicKey);
    var dataToEncrypt = _encoder.GetBytes(data);
    var encryptedByteArray = rsa.Encrypt(dataToEncrypt, false).ToArray();
    var length = encryptedByteArray.Count();
    var item = 0;
    var sb = new StringBuilder();
    foreach (var x in encryptedByteArray)
    {
     item++;
     sb.Append(x);

     if (item &lt; length)
      sb.Append(&quot;,&quot;);
    }

    return sb.ToString();

   }
   catch (Exception)
   {
    throw new RSAException();
   }
  }

  public class RSAException : Exception {

   public RSAException() : base(&quot;RSA Encryption Error&quot;) {}

  }
 }
}
</pre>
<p>The one difference I did notice between the action filter and handler was in the way unhandled errors were passed back to the client. For example, with an action filter, a missing authorization token would have the following rendered to the client: </p>
<p><a href="http://codebetter.com/johnvpetersen/files/2012/04/image11.png"><img src="http://codebetter.com/johnvpetersen/files/2012/04/image11-300x83.png" alt="" width="300" height="83" /></a></p>
<p>On the other and, the message handler would render the same error the client this way:</p>
<p><a href="http://codebetter.com/johnvpetersen/files/2012/04/image11.png"><img src="http://codebetter.com/johnvpetersen/files/2012/04/image21-300x122.png" alt="" width="300" height="122" /></a></p>
<p>You may have noticed I changed the linq calls from First to FirstOrDefault. I got flamed a bit for using just First &#8211; and then letting the exception deal with the results in the event a value could not be found. I still contend that using an exception or checking the nullity of a value doesn&#8217;t make that much of a difference. In the case of checking for the existence of a header, it&#8217;s a moot point because if you invoke code like this:</p>
<pre class="brush: csharp; title: ; notranslate">
var token =
  request.Headers.GetValues(&quot;Authorization-Token&quot;).FirstOrDefault();
</pre>
<p>and the Authorization-Token header does not exist, you never get to the FirstOrDefault() Linq Query&#8230;:-) As it turns out, you have to wrap that call in a try catch anyway &#8211; at least if you wish to present to the client a predictable and useful message. Always take with a grain of salt when somebody espouses &#8220;best practice&#8221; or something being a &#8220;bad practice&#8221; or &#8220;bad form&#8221;. No question, there are established good/best practices out there. Those practices however, are quantifiable and verifiable through empirical evidence. Anything else is simply a matter of opinion and preference. AND &#8211; context means everything. What may be a good/best practice in one scenario may not be so in another scenario. And often, technology has little to nothing to do with the equation. For example, Dependency Injection is a good practice and is often, a best practice. BUT &#8211; in a shop where the concept is new, foreign or not understood, if it presents a bar to shipping software, it may not be a best practice for that shop &#8211; at that time. One of the many reasons why I quickly brush off notions of what best practices are and are not when asked.. <img src='http://codebetter.com/johnvpetersen/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  A bit of a rant on my part. I definitely appreciate the comments &#8211; but rest assured, I&#8217;ll push back a bit when I think conclusions are offered absent a premise. Sorry..that&#8217;s the lawyer in me that is now hard wired!!</p>
<div class="shr-publisher-414"></div><!-- Start Shareaholic LikeButtonSetBottom Automatic --><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><div class='shareaholic-like-buttonset' style='float:none;height:30px;'><a class='shareaholic-fblike' data-shr_layout='button_count' data-shr_showfaces='false' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F04%2Fmoving-from-action-filters-to-message-handlers%2F' data-shr_title='Moving+from+Action+Filters+to+Message+Handlers'></a><a class='shareaholic-googleplusone' data-shr_size='medium' data-shr_count='true' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F04%2Fmoving-from-action-filters-to-message-handlers%2F' data-shr_title='Moving+from+Action+Filters+to+Message+Handlers'></a><a class='shareaholic-tweetbutton' data-shr_count='none' data-shr_href='http%3A%2F%2Fcodebetter.com%2Fjohnvpetersen%2F2012%2F04%2F04%2Fmoving-from-action-filters-to-message-handlers%2F' data-shr_title='Moving+from+Action+Filters+to+Message+Handlers'></a></div><div style="clear: both; min-height: 1px; height: 3px; width: 100%;"></div><!-- End Shareaholic LikeButtonSetBottom Automatic --><img src="http://feeds.feedburner.com/~r/CodeBetter/~4/0HJhKFSYaf0" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/MatthewPodwysocki/~4/-MoSoucEPHo" height="1" width="1"/>]]></content:encoded>
							<wfw:commentRss>http://codebetter.com/johnvpetersen/2012/04/04/moving-from-action-filters-to-message-handlers/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
					<feedburner:origLink>http://codebetter.com/johnvpetersen/2012/04/04/moving-from-action-filters-to-message-handlers/</feedburner:origLink><feedburner:origLink>http://feedproxy.google.com/~r/CodeBetter/~3/0HJhKFSYaf0/</feedburner:origLink></item>
	  </channel>
</rss><!-- Dynamic page generated in 5.281 seconds. --><!-- Cached page generated by WP-Super-Cache on 2012-05-27 22:24:59 --><!-- Compression = gzip -->

