<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	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:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>The Amazing Blog</title>
	<atom:link href="http://blog.theamazingrando.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.theamazingrando.com</link>
	<description>Essays and Rants from a Web Curmudgeon</description>
	<lastBuildDate>Wed, 19 Oct 2016 16:04:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.theamazingrando.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>The Amazing Blog</title>
		<link>http://blog.theamazingrando.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.theamazingrando.com/osd.xml" title="The Amazing Blog" />
	<atom:link rel='hub' href='http://blog.theamazingrando.com/?pushpress=hub'/>
	<item>
		<title>The Conductor Pattern</title>
		<link>http://blog.theamazingrando.com/2012/05/01/the-conductor-pattern/</link>
		<pubDate>Tue, 01 May 2012 00:26:07 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=156</guid>
		<description><![CDATA[The Conductor Pattern Objects on Rails A movement has been growing over the last several months to make our Rails applications more object-oriented. One of the most popular recently has been Avdi Grimm&#039;s Objects on Rails. In it, he talks about an alternative to the Presenter pattern, which he calls Exhibits (and both of which [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=156&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>The Conductor Pattern</h1>
<h2>Objects on Rails</h2>
<p>A movement has been growing over the last several months to make our Rails applications more object-oriented. One of the most popular recently has been <a href="http://objectsonrails.com/">Avdi Grimm&#039;s Objects on Rails</a>. In it, he talks about an alternative to the Presenter pattern, which he calls Exhibits (and both of which are subsets of the Decorator pattern). I&#039;ve been using another form of this, which may or may not be called a Conductor.</p>
<p>Most of these patterns come from the Java world, and Smalltalk before that. They have very specific rules about how they can be used (read-only, wrap methods on a single object, etc). In the Ruby world, however, its flexible object model and powerful metaprogramming features mean we can be a little more lazy about those rules. The Conductor pattern is an implementation of what Martin Fowler&#039;s PoEAA calls a <a href="http://martinfowler.com/eaaCatalog/unitOfWork.html">Unit of Work</a>. Specifically, it wraps one or more models, and can be bidirectional, so it can decorate attributes of the models as well as update them.</p>
<p>I gave a talk a couple years ago at Mountain.rb entitled <a href="http://www.confreaks.com/videos/422-mountainrb2010-forms-don-t-have-to-be-this-complicated">Forms Don&#039;t Have to be this Complicated</a>. In it, I spoke about how terrible Rails is at managing forms, particularly ones that deal with several related objects. I outlined a couple solutions, none of which were very good. I have recently been using this Conductor pattern for these complicated forms, and it seems to have alleviated most of the pain. The ability to wrap multiple models means it can handle the nested associations, and being bidirectional makes it perfect for forms.</p>
<p>In this post, I&#039;m going to show you a couple uses of the Conductor pattern, as well as a library I wrote that implements it.</p>
<h2>GoldPlating</h2>
<p>In Ruby, writing an implementation of the Conductor library is trivial with the help of ActiveModel. The entire implementation is only 60 LOC. I haven&#039;t bothered making a gem of it yet, but <a href="https://gist.github.com/2565340">here&#039;s a gist</a>. Just toss it in your Rails <code>lib/</code> dir and require it.</p>
<p>Here&#039;s how to use it:</p>
<pre><code class="ruby">class Registration
  include GoldPlating

  wrap Account, :name
  wrap User,    :email, :password

  validates_presence_of :account_name,
                        :user_email,
                        :user_password,
                        :message =&gt; &quot;Required&quot;

  validates_format_of :user_email,
                      :with =&gt; /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+\z/,
                      :message =&gt; &quot;Not an Email&quot;,
                      :if =&gt; lambda { user_email.present? }

  validates_length_of :user_password,
                      :minimum =&gt; 5,
                      :message =&gt; &quot;Too short&quot;,
                      :if =&gt; lambda { user_email.present? }


  def save
    super &amp;&amp;
      Membership.create(account: account, user: user)
  end

end
</code></pre>
<p>Here, we have two models, <code>Account</code> and <code>User</code>. In this example app, a <code>User</code> can have access to several <code>Accounts</code> which might represent a business entity, similar to how Github Organizations work. When a user signs up, we want to automatically create but their <code>User</code> for login, and the initial <code>Account</code> they&#039;ll belong to. Because attribute names may overlap, <code>GoldPlating</code> prefixes them with the model name. <code>Account#name</code> becomes <code>Registration#account_name</code>.</p>
<h3>Validations</h3>
<p>I&#039;ve also added some validations to the Registration class. Sometimes different forms dealing with the same models have different valid states for those models, which validation contexts attempt to solve. I think having validations on the wrapper object is a much more elegant solution, leaving the validations on the model objects to simply validate whats needed to stick the object in the database, or is required of the model for the business logic in the rest of the app.</p>
<p>It also lets you have separate human-readable error messages closer to the view, leaving your model validations simpler. For example, if I was requiring users to confirm their email or password, this would be an excellent place to put the <code>validates_confirmation_of</code>, leaving the model clear. It also makes it so that you don&#039;t have to set the <code>_confirmation</code> fields in your tests or factories when creating the objects.</p>
<p>The downside is that you have to duplicate some of your model validations in the conductor, like the validation on <code>email</code> above. I don&#039;t have an elegant solution for this yet.</p>
<h3>Controller</h3>
<p>When writing a registration form that needs to create both objects, the normal Rails method would be to separate out the <code>params</code> in the controller, and create one of each object then associate them. This gets tricky, however, when one or the other fails to validate. Also, it puts a lot of logic in the controller. Using this conductor however, our controller is simple:</p>
<pre><code class="ruby">class RegistrationController &lt; ApplicationController
  skip_before_filter :require_login

  def new
    @registration = Registration.new
  end

  def create
    @registration = Registration.new(params[:registration])

    if @registration.valid?
      @registration.save
      auto_login @registration.user
      redirect_back_or_to root_path, :notice =&gt; &quot;Registration Successful&quot;
    else
      render :new
    end
  end
end
</code></pre>
<p>The form in the view is, too:</p>
<pre><code class="haml">= form_for @registration, url: signup_path do |form|

  = form.text_field :account_name

  = form.email_field :user_email

  = form.password_field :user_password
</code></pre>
<p>The controller and view can interact with the <code>Registration</code> conductor like any other ActiveModel-compliant object. In fact, this is the entire implementation. GoldPlating handled the object initialization, and assignment of the params to the right objects. GoldPlating also handled saving the objects it wraps, all we had to do was implement a <code>#save</code> to create the <code>Membership</code> association record between the newly-created <code>User</code> and <code>Account</code> records.</p>
<h2>So much easier</h2>
<p>I&#039;ve been using this Conductor pattern quite liberally throughout my recent projects. Having this wrapper object to contain all the business logic related to presenting multiple objects to a form, and consuming and validating that form&#039;s output, greatly simplifies my code. It also makes testing a breeze. I can test all the edge-case behaviour via tests that exercise the conductor, rather than full-stack tests through the full Rails request stack.</p>
<p>I&#039;ve found that having a single conductor object for each form is the best way to go. It does lead to some code duplication, which might be alleviated some by including modules of shared methods, but overall the code in the conductor is simple and focused enough that the duplication has not (yet) been a major problem. It really helps to isolate the User-Interface of the forms from the data model, and associated business logic.</p>
<p>Some of the really useful places for conductors have been <code>Registration</code>, <code>UserPreferences</code>, <code>PasswordReset</code>, <code>ManipulateAuthorization</code>. You&#039;ll notice that all of these involve some sort of <code>User</code> model, but each in a different way. Its nice having all the logic for each process encapsulated in a single, distinct place.</p>
<p>Feel free to grab <code>GoldPlating</code> from that gist, or if there&#039;s enough interest, I can package it up as a gem.</p><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/156/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/156/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=156&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
		<item>
		<title>Annoucing ProgressBar</title>
		<link>http://blog.theamazingrando.com/2011/04/10/announcing-progress_bar/</link>
		<pubDate>Sun, 10 Apr 2011 16:17:12 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=158</guid>
		<description><![CDATA[Annoucing ProgressBar ProgressBar I was working on a script to sync hundreds of thousands of records between two databases, and wanted a simple way to keep track of progress. I couldn&#039;t find one that was easy to use and did what I wanted, so I wrote my own. Not much more introduction needed, how about [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=158&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>Annoucing ProgressBar</h1>
<h1>ProgressBar</h1>
<p>I was working on a script to sync hundreds of thousands of records<br />
between two databases, and wanted a simple way to keep track of<br />
progress. I couldn&#039;t find one that was easy to use and did what I<br />
wanted, so I <a href="https://github.com/paul/progress_bar">wrote my own</a>. Not much more introduction needed, how about<br />
a simple example?</p>
<pre><code>$ cat examples/simple.rb

require &#039;progres_bar&#039;
bar = ProgressBar.new

100.times do
  sleep 0.1
  bar.increment!
end

$ ruby examples/simple.rb
[#########################                                      ] [ 39/100] [ 39%] [00:04] [00:06] [  9.12/s]
</code></pre><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/158/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=158&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
		<item>
		<title>The Road to Better Authorization</title>
		<link>http://blog.theamazingrando.com/2010/11/21/the_road_to_better_auth/</link>
		<pubDate>Sun, 21 Nov 2010 22:08:14 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=160</guid>
		<description><![CDATA[The Road to Better Authorization The Problem I have several Google accounts: My personal email, Google Apps at my employer, and Gmail for my domain. I use my personal email all the time, and have several Google Docs spreadsheets and letters. Our company uses Google Docs and Sites. Its extremely annoying that switching between these [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=160&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>The Road to Better Authorization</h1>
<h2>The Problem</h2>
<p>I have several Google accounts: My <a href="mailto:psadauskas@gmail.com">personal email</a>, Google Apps at <a href="http://absolute-performance.com">my employer</a>, and Gmail for <a href="http://theamazingrando.com">my domain</a>. I use my personal email all the time, and have several Google Docs spreadsheets and letters. Our company uses Google Docs and Sites. Its extremely annoying that switching between these accounts is brittle, and unpredictable. The same situation existed on Github between my personal and the company account, before they added &quot;Organizations&quot;.</p>
<p>The other problem is poor integration with the hundreds of accounts I have across various sites. I have a simple password that I use for throwaway, which is still horribly insecure. The alternative is a password manager such as KeePass or 1Password, but browser integration is poor or non-existent.</p>
<p>I use the <a href="http://chrome.desc.se/">Google Mail Checker Plus</a> extension for Chrome, which can automatically redirect me to the Gmail inbox for each account, and from there I can follow links to Docs or Sites. However, all the accounts are &quot;logged in&quot;, and I occasionally experience trouble and get permission denied errors when I click on a document link in my list.</p>
<p>My main workaround at this point is to use Chrome for normal browsing and personal accounts, and Firefox, which I use for development &amp; debugging anyways, has the saved passwords for company accounts. This has worked for awhile, but as I amass various side-projects, and need a 3rd login for some sites (Github and Amazon AWS seem to be the main ones), I don&#039;t want to have to maintain more browser profiles.</p>
<p>Ideally, the browser and sites would integrate and work together to manage everything automatically, but this is a chicken and egg problem. The solution will likely have to be completed in stages.</p>
<p>OpenID and OAuth are attempts at solving this on the server side, but they are complicated. And they need to be, because there&#039;s several parties involved, all needing to handshake with each other and prove everyone&#039;s identity. I feel a simpler solution, and a much better way to handle this, would be in the browser itself. Even the technical name for the browser, &quot;User Agent&quot;, indicates its purpose. I see it as the concierge at an expensive hotel. They have the inside knowledge of the city, and the personal contacts, to get you anything you need. Want blueberry and peanut-butter waffles at 11pm? Call the concierge and he&#039;ll figure out how to get it for you.</p>
<p>Same for the browser. It&#039;s your concierge for the web. You don&#039;t need to know HTML and CSS to be able to use a website, the browser renders the text and images into a sensible layout for you to read. If a page moved, you don&#039;t have to type in the new location manually, the browser automatically goes there for you. If you need credentials to visit your Facebook page, you don&#039;t have to deal with the ugly bouncer directly, the concierge coughs and politely asks you for your password. What I&#039;m proposing is promoting your concierge to your own personal assistant. You shouldn&#039;t even need to know there <em>is</em> a bouncer, because your assistant has already made arrangements and you can walk right in.</p>
<h2>Phase 1</h2>
<p>The first step is a browser extension for managing all my accounts at various sites. On a site where I have several accounts, or a personal account and a shared corporate account, it would be great to have a simple way to switch between them. When I come to a page, but want to view it as a different account, I have to:</p>
<ol>
<li>Find and click a &quot;Sign Out&quot; link.</li>
<li>Find the &quot;Sign In&quot; link.</li>
<li>Clear the &quot;username&quot; field of the form, and replace it with the other account&#039;s username.</li>
<li>Hope the browser remembers the other account&#039;s password, or look it up and fill it in.</li>
<li>Navigate back to the original page.</li>
</ol>
<p>Compare that to a browser extension or built-in feature:</p>
<ol>
<li>Click &quot;Account Manager&quot; toolbar button, which provides a list of known accounts for the site.</li>
<li>Select the account from the list.</li>
</ol>
<p>The implementation would be straightforward. Just save all the cookies currently associated with the domain and tie them to that account, then load the previously stored cookies for the account that was selected, and re-request the page with the new cookies. If the page is using http authentication, the browser only has to change which Authorization header it is providing to the site.</p>
<p>There have been various attempts to do this, but nothing ever seems completed. I haven&#039;t attempted my own, so maybe there&#039;s some complication that I&#039;m missing. Mozilla has a proposal for such an extension called <a href="https://wiki.mozilla.org/Labs/Weave/Identity/Account_Manager">Account Manager</a>, but there seems to be no real activity since a few weeks after the project was announced back in March 2010. This seems like a real win for users, I can&#039;t understand why no browser has this built-in, or even an extension. I&#039;d switch to Opera or Safari in a minute if they offered this, its a killer feature for a browser.</p>
<p>There&#039;s also programs such as <a href="http://www.keepassx.org/">KeePassX</a>, <a href="http://agilewebsolutions.com/onepassword">1Password</a>, and <a href="https://lastpass.com/">LastPass</a>, some of which include browser plugins that can manage passwords for you. These all seem to be standalone password managers first, with the browser integration coming 2nd, which can sometimes be pretty clunky. Phase one needs to be a browser extension specifically designed to integrate with web site logins.</p>
<h2>Phase 2</h2>
<p>The next phase would be for the browser to be able to manage account creation. Since the browser can manage my accounts, it would be handy if it would create them, by automatically filling out the sign up form at the site. Browsers already have my name, email, address, etc, from being able to auto-fill forms. It could auto-fill the sign up form with my personal information (or suitably anonymized information if I choose), create a login and a random password, and save all that with the account manager.</p>
<p>Undoubtedly, this would require &quot;rules&quot; for lots of sites, similar to adblock extensions, to know which signup fields are which, and how exactly to fill out the signup form. Perhaps some JSON to indicate field names, or even some javascript.</p>
<p>For example, say we have a signup form (like, say, Facebook&#039;s, with non-essential tags stripped out):</p>
<pre><code>&lt;form method=&quot;post&quot; id=&quot;reg&quot; name=&quot;reg&quot;&gt;
  &lt;input type=&quot;text&quot; class=&quot;inputtext&quot; id=&quot;firstname&quot; name=&quot;firstname&quot;&gt;
  &lt;input type=&quot;text&quot; class=&quot;inputtext&quot; id=&quot;lastname&quot; name=&quot;lastname&quot;&gt;
  &lt;input type=&quot;text&quot; class=&quot;inputtext&quot; id=&quot;reg_email__&quot; name=&quot;reg_email__&quot;&gt;
  &lt;input type=&quot;text&quot; class=&quot;inputtext&quot; id=&quot;reg_email_confirmation__&quot; name=&quot;reg_email_confirmation__&quot;&gt;
  &lt;input type=&quot;password&quot; class=&quot;inputtext&quot; id=&quot;reg_passwd__&quot; name=&quot;reg_passwd__&quot; value=&quot;&quot;&gt;
  &lt;select class=&quot;select&quot; name=&quot;sex&quot; id=&quot;sex&quot;&gt;&lt;option value=&quot;1&quot;&gt;Female&lt;option value=&quot;2&quot;&gt;Male&lt;/select&gt;
  &lt;select id=&quot;birthday_month&quot; name=&quot;birthday_month&quot;&gt;...&lt;/select&gt;
  &lt;select name=&quot;birthday_day&quot; id=&quot;birthday_day&quot;&gt;...&lt;/select&gt;
  &lt;select name=&quot;birthday_year&quot; id=&quot;birthday_year&quot;&gt;...&lt;/select&gt;
  &lt;input value=&quot;Sign Up&quot; type=&quot;submit&quot;&gt;
&lt;/form&gt;
</code></pre>
<p>Since names like <code>&quot;reg_email__&quot;</code> are rather nonstandard, we&#039;ll need some way to map the fields we know for our profile to the fields on the website form. The mappings are probably too complicated to be one-to-one with a simple XML or JSON file, however a JavaScript function could be executed:</p>
<pre><code>function performSignup(profile) {
  $(&quot;#firstname&quot;).val(profile.first_name);
  $(&quot;#lastname&quot;).val(profile.last_name);
  $(&quot;#reg_email__&quot;).val(profile.email);
  $(&quot;#reg_email_confirmation__&quot;).val(profile.email);
  $(&quot;#reg_passwd__&quot;).val(profile.generate_random_password());
  $(&quot;#sex&quot;).val(profile.gender == &quot;male&quot; ? &quot;2&quot; : &quot;1&quot;);
  $(&quot;#birthday_day&quot;).val(profile.birthday.day);
  $(&quot;#birthday_month&quot;).val(profile.birthday.month);
  $(&quot;#birthday_year&quot;).val(profile.birthday.year);

  $(&quot;#reg&quot;).submit();
}
</code></pre>
<p>Some helpers to make that less verbose, and getting contributions to write rules for the most common sites, and now your browser can perform signups for you. If this becomes popular or compelling to websites to implement, a JavaScript browser API could be exposed so that websites could implement the signup function themselves.</p>
<pre><code>
  accountManager.setSignup(function(profile) { ... } );

</code></pre>
<p>Where <code>setSignup</code> is the browser API function to call to assign your website&#039;s signup function, and <code>profile</code> is an object containing the personal information provided by the user.</p>
<h2>Phase 3</h2>
<p>Phase 3 involves developing an API between the browser and the web page directly. It can be a simple extension to some of the new HTML5 APIs out there for dealing with video or local storage in javascript. Hopefully (but not likely, given how similar projects have played out before), each browser that implements this would have a similar API that common elements could be used.</p>
<h2>Conclusion</h2>
<p>In conclusion, authentication for web services sucks, and has for a long time. The right place to manage this is in the browser itself, rather than a complicated handshaking protocol between servers. Writing a browser extension like the one described in Phase 1 is on my TODO list, but I know nothing about browser extensions, and have plenty of other projects to keep me busy. If someone out there is willing to take this on, drop me a line, I&#039;d certainly love to help.</p>
<h2>Extra Credit</h2>
<ul>
<li>Store all the data in the cloud, so its not lost in reformats, and can be shared between computers. Even better, have an interchange format so it can be shared between browsers, and your phone, so you can login to sites from wherever.</li>
<li>An extension to the built-in HTTP Auth methods, something more secure than the MD5 used in Digest Auth. Properly implemented with nonces and cnonces, Digest Auth is still pretty secure, but it will only be a matter of time before MD5 can be brute-forced in a reasonable amount of time. Or maybe just convince everyone that all HTTP should be over SSL, and then we can just use Basic Auth. Once people start using browser authentication managers, no-one will care about styling the login form any more. Maybe the browser could load the favicon, or follow a <code>&lt;link&gt;</code> tag to a logo image for the site being logged in to.</li>
</ul><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/160/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/160/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=160&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
		<item>
		<title>Dear Microsoft: Please Do Pinned Menus Like This Instead</title>
		<link>http://blog.theamazingrando.com/2010/09/25/using_the_link_element/</link>
		<pubDate>Sat, 25 Sep 2010 16:04:36 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=162</guid>
		<description><![CDATA[Dear Microsoft: Please Do Pinned Menus Like This Instead With the IE9 betas beginning to come out, Microsoft have introduced an interesting new feature they&#039;re calling pinned sites. For more details about how it works, you can check out the Ars Technica preview. Essentially, you put several ms-vendor specific meta tags in the html of [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=162&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>Dear Microsoft: Please Do Pinned Menus Like This Instead</h1>
<p>With the IE9 betas beginning to come out, Microsoft have introduced an interesting new feature they&#039;re calling <a href="http://msdn.microsoft.com/en-us/library/gg131029(VS.85).aspx">pinned sites</a>. For more details about how it works, you can check out the <a href="http://arstechnica.com/microsoft/news/2010/09/inside-internet-explorer-9-redmond-gets-back-in-the-game.ars/4">Ars Technica preview</a>. Essentially, you put several ms-vendor specific <code>meta</code> tags in the html of your header that describe the menu. The example given on the Ars preview uses this markup:</p>
<pre><code>&lt;meta name=&quot;application-name&quot; content=&quot;Ars Technica&quot;/&gt;
&lt;meta name=&quot;msapplication-starturl&quot; content=&quot;http://arstechnica.com/&quot;/&gt;
&lt;meta name=&quot;msapplication-tooltip&quot; content=&quot;Ars Technica: Serving the technologist for 1.2 decades&quot;/&gt;
&lt;meta name=&quot;msapplication-task&quot; content=&quot;name=News;action-uri=http://arstechnica.com/;icon-uri=http://arstechnica.com/favicon.ico&quot;/&gt;
&lt;meta name=&quot;msapplication-task&quot; content=&quot;name=Features;action-uri=http://arstechnica.com/features/;icon-uri=http://static.arstechnica.net/ie-jump-menu/jump-features.ico&quot;/&gt;
&lt;meta name=&quot;msapplication-task&quot; content=&quot;name=OpenForum;action-uri=http://arstechnica.com/civis/;icon-uri=http://static.arstechnica.net/ie-jump-menu/jump-forum.ico&quot;/&gt;
&lt;meta name=&quot;msapplication-task&quot; content=&quot;name=One Microsoft Way;action-uri=http://arstechnica.com/microsoft/;icon-uri=http://static.arstechnica.net/ie-jump-menu/jump-omw.ico&quot;/&gt;
&lt;meta name=&quot;msapplication-task&quot; content=&quot;name=Subscribe;action-uri=http://arstechnica.com/subscriptions/;icon-uri=http://static.arstechnica.net/ie-jump-menu/jump-subscribe.ico&quot;/&gt;
</code></pre>
<p>&#8230;to produce this Windows 7 &quot;pinned menu&quot;:</p>
<p><img src="http://static.arstechnica.com/ie-9-beta-1/ie9-ars-jump-list.png" alt="Ars Technica pinned menu"></p>
<p>Kroc Camen at <a href="http://camendesign.com/">Camen Design</a> has a <a href="http://camendesign.com/blog/stop_this_madnessels">pretty decent rant</a> about how he thinks this is a bad idea. However, aside from the annoying proprietary <code>.ico</code> image format, the way Microsoft chose to use the <code>meta</code> element it isn&#039;t nearly as bad as what Mr. Camen proposes in its stead.</p>
<h2>The <code>Meta</code> Element</h2>
<p>I take no issue with Microsoft&#039;s use of the <code>meta</code> element. It was always intended to be used by vendors for browser-specific features. From the <a href="http://wiki.whatwg.org/wiki/MetaExtensions">HTML5 working group wiki</a>:</p>
<blockquote>
<p>You may add your own values to this list, which makes them legal HTML5 metadata names. We ask that you try to avoid redundancy; if someone has already defined a name that does roughly what you want, please reuse it.</p>
</blockquote>
<p>That said, this implementation is far from ideal. It is extremely verbose, 8 lines and over 1KB of text. Not surprising, as Microsoft and IE have always had issues with <a href="http://www.gethifi.com/blog/browser-rest-http-accept-headers">extreme</a> <a href="http://stackoverflow.com/questions/2838635/ajax-microsoft-com-vs-cookieless-domain-for-cdn">verbosity</a>. This text will have to be sent with every page that a user might possibly want to &quot;pin&quot; your site from. Every page * every visitor * 1KB = a whole lot of bandwidth.</p>
<p>Camen&#039;s proposal is to use the new HTML5 <code>menu</code> element, in the body of the page. Not only does this have the same problems as above, its going to break accessibilty. Even if its it hidden from view by CSS, screen readers and other devices are going to be confused by having a <code>menu</code> stuck in the page, that is only tangentially related to the page&#039;s content.</p>
<p>Luckily, there is a perfectly acceptable solution: the <code>link</code> element.</p>
<h2>The <code>Link</code> Element</h2>
<p>You&#039;re probably already familiar with <a href="http://dev.w3.org/html5/spec/Overview.html#the-link-element">this element</a>; you use it any time you want to attach a stylesheet to your page.</p>
<pre><code>&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/style.css&quot;&gt;
</code></pre>
<p>The <code>rel</code> attribute is a space-separated list of keywords that describe what <em>relationship</em> the linked content has to this page. So the IE pinned menu markup above could easily be replaced with:</p>
<pre><code>&lt;link rel=&quot;ms-pinned-menu&quot; type=&quot;application/xml&quot; href=&quot;/pinned-menu.xml&quot;&gt;
</code></pre>
<p>Then <code>pinned-menu.xml</code> could be simple xml (or HTML5 menu!) describing the menu. By doing it this way, web applications gain all the same benefits as serving linked stylesheets: it can be cached, and hosted as a static file on a CDN. Additionally, its much easier to extend the XML dialect as more browsers want to support Windows 7 pinned menus. Further, its a jumping-point to more integrated browser features, such as Android&#039;s &quot;Menu&quot; button, and single-page browser wrappers like Fluid and Prism.</p>
<p>I know its too late to get Microsoft to fix this in IE9, but hopefully the other browser vendors will be more forward-thinking, and let us developers do this the easy way, without adding kilobytes of additional markup to all our pages.</p><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/162/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/162/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=162&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>

		<media:content url="http://static.arstechnica.com/ie-9-beta-1/ie9-ars-jump-list.png" medium="image">
			<media:title type="html">Ars Technica pinned menu</media:title>
		</media:content>
	</item>
		<item>
		<title>About this Blog</title>
		<link>http://blog.theamazingrando.com/2010/07/01/about-this-blog/</link>
		<pubDate>Thu, 01 Jul 2010 23:16:13 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=164</guid>
		<description><![CDATA[About this Blog After nearly a year on hiatus, I&#039;m finally ready to start blogging again. I have several neat projects I&#039;ve been working on over the last several months, and I need a place to write about them. Why I stopped using WordPress My self-hosted WordPress blog on my Slicehost served me well over [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=164&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>About this Blog</h1>
<p>After nearly a year on hiatus, I&#039;m finally ready to start blogging again. I have several neat projects I&#039;ve been working on over the last several months, and I need a place to write about them.</p>
<h2>Why I stopped using WordPress</h2>
<p>My <a href="http://theamazingrando.com/blog">self-hosted WordPress blog</a> on my Slicehost served me well over the last few years. With a hodge podge of plugins and hacks, I was able to write my posts in markdown. I was still stuck writing them in the textarea of the browser, or copy-pasting them from my real editor to the browser, but it worked well enough. Eventually, though, I was updating WordPress for security vulnerabilities more often than I was posting, and it was collecting a ton of spam comments. I decided that I didn&#039;t want to be in charge of that extra stuff any more.</p>
<p>I made several attempts to port my blog over to something else. I had a few simple goals:</p>
<ul>
<li>The canonical place for my posts is git. Version control of the posts is definitely the way to go.</li>
<li>I just want to write content, not moderate spam, or manage plugins.</li>
<li>I don&#039;t want to maintain blogging software.</li>
</ul>
<p>I looked for several solutions, but nothing really fit the bill. Posterous&#039;s announcement that they supported markdown got the wheels turning, though. Credit for the final bits go to <a href="http://barelyenough.org/">Peter Williams</a> and <a href="http://twitter.com/spikex">@spikex</a>, who got me started about how to manage drafts that I don&#039;t want published.</p>
<h2>Importing WordPress</h2>
<p>First, however, I had to get all my old posts out of WordPress and into a git repo. I hacked together <a href="http://github.com/paul/blog.theamazingrando.com/blob/master/lib/import.rb">this little script</a> which parsed the WordPress XML dump. It goes over the posts and creates a branch for each, adds the markdown for the post, then merges the branch into master. I did this so that I could get a bit of metadata about the posts in the git repo. The first commit for a post would be the &quot;created&quot; date, and the commit when it was merged into master would be the &quot;published&quot; date.</p>
<p>Only after I did all this did I figure out that Posterous only exposed a &quot;date&quot;, but this worked well together with another shortcoming: the lack of metadata on the post itself. I originally wanted a way to handle updating existing posts, but I had no metadata to find the post again. So for the post&#039;s &quot;date&quot;, I used the most-recent commit date, at the time of the sync. As long as I keep the post &quot;Title&quot; unique, I&#039;ll be able to find the post again, and update the content, but not the date.</p>
<h2>Syncing with Posterous</h2>
<p>So the official place for all my posts is my own git repo, where I can track changes, and manage it. I get to write using whatever editor I feel like, instead of a textarea in a browser, and I get to write them in markdown. I have a <a href="http://github.com/paul/blog.theamazingrando.com/blob/master/lib/sync.rb">script</a> that I use to publish all my posts to Posterous. The script is rather dumb, and just updates everything that needs updated. I had planned on making it better, but due to some shortcomings in the Posterous API, and in the <a href="http://github.com/twoism/postly">postly</a> ruby gem, I took the lazy way out. You can see in the script where I had to monkey-patch the postly gem to make it even work at all. Posterous also needs to read my last <a href="http://blog.theamazingrando.com/your-web-service-might-not-be-restful-if">blog post</a></p>
<p>I wanted to use Posterous&#039;s markdown, but it had its own shortcomings, like it couldn&#039;t handle the metadata, or definition lists, like the <a href="http://maruku.rubyforge.org/">maruku</a> gem can. So just render it myself, and post the html body to Posterous. This means I&#039;ll eventually have to figure out things like syntax highlighting, but since Posterous supports inline gists, maybe I&#039;ll just do that.</p>
<h2>Finally</h2>
<p>So, in conclusion, its not perfect, but it&#039;ll do. I&#039;ll probably write a follow-up post, about what the Posterous API needs to add, since their own docs say its incomplete, and they don&#039;t know what to do with it. It also exposed some flaws in the HTTParty gem, which I hadn&#039;t had exposure to until now. Its not really a bug, but rather a design decision, in that the request method only has two params: <code>post url, options = {}</code>. It tries to be smart about those options, and if you have one called <code>:body</code>, it becomes the body of the request. However, Posterous has a param in their API called <code>&quot;body&quot;</code>, which just confused everybody. Additionally, the postly gem crammed everything in the query parameters, which quickly runs into URL length limits for my admittedly verbose blog posts.</p>
<p>The world would be a better place if everyone would just use <a href="http://github.com/paul/resourceful">Resourceful</a>. <code>&lt;/shameless-plug&gt;</code></p>
<p>Overall, I wrote ~100 lines of Ruby to import my old wordpress blog, and sync the whole thing up to Posterous. I don&#039;t have to host or maintain anything, so its a definite win. I hope it gives my more time to write about all the cool shit I&#039;ve been working on over the last few months, and well as my new project, <a href="http://mongomachine.com">MongoMachine</a>. Stay tuned!</p><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/164/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/164/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=164&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
		<item>
		<title>Your Web Service Might Not Be RESTful If&#8230;</title>
		<link>http://blog.theamazingrando.com/2009/07/20/your-web-service-might-not-be-restful-if/</link>
		<pubDate>Mon, 20 Jul 2009 04:11:45 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=166</guid>
		<description><![CDATA[Your Web Service Might Not Be RESTful If&#8230; The other day, I gave a brief talk about our HTTP Library, Resourceful. After a few minutes of going over the features, it became apparent to me that very few people have taken the time to appreciate the finer points of HTTP. Everyone who calls themself a [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=166&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>Your Web Service Might Not Be RESTful If&#8230;</h1>
<p>The other day, I gave a brief talk about our HTTP Library, <a href="http://github.com/paul/resourceful">Resourceful</a>. After a few minutes of going over the features,<br />
it became apparent to me that very few people have taken the time to appreciate the finer points of HTTP. Everyone who<br />
calls themself a web application developer needs to take a few hours to read <a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">RFC2616: Hypertext Transfer Protocol &#8212; HTTP/1.1</a>.<br />
Its not very long, and increadibly readable for a spec. Print it out, and read a few sections when you go for your<br />
morning &quot;reading library&quot; break. Unfortunately, a great many people got confused by it, and ended up reimplementing a lot<br />
of http in another layer, and thats how we ended up with SOAP and XML-RPC. There&#039;s a good parable about<br />
<a href="http://serialseb.blogspot.com/2009/06/fighting-for-rest-or-tale-of-ice-cream.html">how this all went of the rails for awhile</a>, until some people re-discovered a section in  Roy T. Fielding&#039;s<br />
disseration, &quot;<a href="http://www.ics.uci.edu/%7Efielding/pubs/dissertation/rest_arch_style.htm">Representational State Transfer (REST)</a>&quot;. </p>
<p>Needless to say, REST is making a huge comeback, at least in the agile startup communities. It&#039;s fast, lightweight, and<br />
easy to put together. Ruby on Rails even has excellent support for getting up and running quicky. Sadly, though, it&#039;s<br />
not quite right, and as a result, developers have misconstrued REST yet again, and its making things harder than they<br />
really need to be, and also leading them down a path that leads to lots of headaches in the future. If you&#039;re interested<br />
in learning more about REST, there&#039;s plenty of excellent resources on the <a href="http://rest.blueoxen.net/cgi-bin/wiki.pl?FrontPage">REST Wiki</a>, particularly<br />
<a href="http://rest.blueoxen.net/cgi-bin/wiki.pl?RestInPlainEnglish">REST In Plain English</a>.</p>
<p>For some of my examples, I&#039;m going to pick on the <a href="http://www.pivotaltracker.com/help/api">Pivotal Tracker &quot;RESTful&quot; API</a>. Sorry guys, I needed to<br />
pick someone, and I love your product (I use it every day), but you&#039;re part of the reason for this post. I wanted to<br />
write a client for your service, but its really much harder than it needs to be. The service violates many of the constraints<br />
of REST, and therefore naming it &quot;RESTful&quot; is incorrect. You&#039;re not the only ones, though, so don&#039;t feel bad, nearly<br />
EVERY API that claims to be RESTful isn&#039;t. For a look at one that gets it (mostly) right, check out <a href="http://developer.netflix.com/docs">Netflix</a>.</p>
<h1>If Your Web Services Do Any of These Things, You&#039;re Doing it Wrong</h1>
<ol>
<li>Clients have to read documentation to know the locations of top-level resources.</li>
<li>Clients have to concatenate strings to get to the next resource.</li>
<li>You have an &quot;API/Key/Token&quot; in a header or a url.</li>
<li>You have a version string in a url.</li>
</ol>
<h2>1. Have a Minimum of Starting Points</h2>
<p>If you look at the <a href="http://www.pivotaltracker.com/help/api#api_actions">Available Actions on Pivotal Tracker&#039;s API page</a>, you&#039;ll see they list several<br />
actions that can be performed. This isn&#039;t REST, this is XML-RPC. Nearly everybody gets this one wrong. Due to the<br />
amount of confusion, Roy Fielding <a href="http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">published a post</a> to stop people abusing the term &quot;RESTful&quot; and to try<br />
and clarify what a real RESTful API is. His final point is:</p>
<blockquote>
<p>A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media<br />
types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use<br />
the API). </p>
</blockquote>
<p>The point here is that there should be only one resource that is the starting point for any interaction with the<br />
service. This is called a &quot;well-known&quot; resource, and is never, <em>ever</em> allowed to change locations. If it does change,<br />
you break every single client out there. By publishing a dozen or more well-known resources in their API docs, Tracker<br />
is no longer permitted to change any of them. This increases the maintenance burden, because now they have to maintain<br />
all these resources for the lifetime of the application, or deprecate any third-party clients. </p>
<p>If they had instead added a single resource that described the locations of these other resources, they would have much<br />
more flexibility in the future. An example of the content of such a resource:</p>
<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;services&gt;
  &lt;service&gt;
    &lt;name&gt;AllProjects&lt;/name&gt;
    &lt;href&gt;http://www.pivotaltracker.com/services/projects&lt;/href&gt;
  &lt;/service&gt;
  &lt;service&gt;
    &lt;name&gt;AllActivities&lt;/name&gt;
    &lt;href&gt;http://www.pivotaltracker.com/services/activites&lt;/href&gt;
  &lt;/service&gt;
&lt;/services&gt;
</code></pre>
<p><em>Note: Yes, they list several other actions on their API. However, each of them violates another one of the REST<br />
constraints, so I have ommitted them for the time being.</em></p>
<p>Now every client just needs to know the name of the resource they&#039;re looking for, eg &quot;AllActivites&quot;, and they can<br />
continue as before. If, for some perfectly valid reason, Pivotal decides to change the name of &quot;Activites&quot; to, say,<br />
&quot;Actions&quot;, they only have to modify the <code>href</code> of the &quot;AllActivities&quot; service description, add a &quot;AllActions&quot;<br />
service, and every single client using it by the name instead of a hardcoded href continues to work flawlessly, or<br />
at least as well as it did before. Less maintenance burden on the service developers, and no burden at all for<br />
the developer of a well-written client.</p>
<h2>2. Don&#039;t Make a Client Construct URIs</h2>
<p>In that very same bullet point, Roy continues&#8230;</p>
<blockquote>
<p>From that point on, all application state transitions must be driven by client selection of server-provided choices<br />
that are present in the received representations&#8230;</p>
</blockquote>
<p>If you look at the <a href="http://www.pivotaltracker.com/help/api#api_actions">Tracker API docs Available API Actions</a> for projects, you&#039;ll see &quot;Single<br />
project&quot; and &quot;All my projects&quot;. We already covered how to handle the &quot;AllProjects&quot; resource, an in the example above,<br />
we remove the &quot;Single project&quot; resource entirely. So how do you get to the resource for a single project? Simple, you<br />
follow its link in the &quot;AllProjects&quot; resource.</p>
<pre><code>    &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
    &lt;projects type=&quot;array&quot;&gt;
      &lt;project&gt;
        &lt;href&gt;http://www.pivotaltracker.com/services/v2/projects/1&lt;/href&gt;

        &lt;id&gt;1&lt;/id&gt;
        &lt;name&gt;Sample Project&lt;/name&gt;
        &lt;iteration_length type=&quot;integer&quot;&gt;2&lt;/iteration_length&gt;
        &lt;week_start_day&gt;Monday&lt;/week_start_day&gt;
        &lt;point_scale&gt;0,1,2,3&lt;/point_scale&gt;

        &lt;stories_href&gt;http://www.pivotaltracker.com/services/v2/projects/1/stories?{-join|&amp;|filter,limit,offset}&lt;/stories_href&gt;
        &lt;iterations_href&gt;http://www.pivotaltracker.com/services/v2/projects/1/iterations&lt;/iterations_href&gt;
        &lt;activities_href&gt;http://www.pivotaltracker.com/services/v2/projects/1/activities&lt;/activities_href&gt;
      &lt;/project&gt;
      &lt;!-- ... --&gt;
    &lt;/projects&gt;
</code></pre>
<p>For a client to find a single project, they would know its name. They would GET the list of services, find &quot;AllProjects&quot;<br />
by name, GET the &quot;href&quot; provided, and look for the project &quot;Sample Project&quot; by name. They could then use the href attribute<br />
to obtain the single resource for the project. Additionally, we also have links to all the actions in the docs that required a<br />
<code>PROJECT_ID</code> in the url. To get the iterations or activities for a project, a client has to only locate the project, and<br />
follow the links.</p>
<p>You should also notice the part of the <code>stories_href</code> enclosed in <code>{braces}</code>. This is known as a <a href="http://bitworking.org/projects/URI-Templates/">URI Template</a>,<br />
and is very handy. If you noticed in pivotals API docs, they had three ways of getting stories: All stories, stories by<br />
a filter, and stories by a limit and offset. I took the liberty of combining these into single href, using the template<br />
to describe the query parameters. A ruby client, using the <code>Addressable::URI</code> library, could fill out that uri like this:</p>
<pre><code>template = Addressable::Template(stories_href)
template.expand({
  &quot;filter&quot; =&gt; &#039;label:&quot;needs feedback&quot; type:bug&#039;
})
</code></pre>
<p>All these extra requests might seem like a rather long way of going about it, however, the advantages are immense:</p>
<p>Should Tracker become huge, and everybody and their grandmother starts using it to keep track of their development projects,<br />
Tracker could outstrip the load of a single database. Since it appears they are using <code>AUTOINCREMENT id</code> columns for the<br />
project id, sharding the <code>projects</code> table is going to be hard. However, if they were to start using <code>UUID</code> columns for<br />
project ids, then sharding is a whole lot less complicated. However, if they change the project id in the API, everyone&#039;s<br />
clients break. If clients were to instead follow the href, they can do whatever they want to the id, and existing<br />
clients will have no trouble at all following.</p>
<p>But wait, it gets better. What happens if the service still isn&#039;t fast enough, for any number of perfectly plausible<br />
reasons? Because they&#039;re using hrefs, they can put <em>anything they want</em> there. Say they decide to shard the application<br />
servers, so every project with an odd-numbered id goes to <code>www1.pivotaltracker.com</code>, and everything even-numbered goes<br />
to <code>www2.pivotaltracker.com</code>. They just have to update the links, and everyone&#039;s client continues working.</p>
<p>If all resources are specified like this, then a client can get to every resource from that one starting point. You are<br />
free to move, rename, and add resources as you desire, without making things complicated for your API clients. Less<br />
maintenance burden on you, and none on your users.</p>
<h2>Don&#039;t put an &quot;API Token&quot; in a custom header, or in the URIs</h2>
<p>While there&#039;s nothing technically un-RESTful about this, its still annoying to your clients. And unless you have a<br />
full-time security expert on your staff, you probably did it wrong, and its not nearly as secure as you think it is.<br />
It&#039;s also vulnerable to man-in-the-middle attacks and replay attacks, unless you use SSL. And if you <strong>do</strong> use SSL,<br />
then you&#039;ve thrown away one of the major advantages of HTTP, which is caching. Just about every HTTP server and<br />
proxy are able to handle caching, and if they operate to spec, they&#039;re not allowed to cache SSL documents. I&#039;ll get<br />
more into caching in a future blog post, just realize that it can be immensely beneficial to the performance of your<br />
application, and you&#039;re going to want to do everything you can to facilitate that.</p>
<p>Luckily, you have a third option: HTTP Digest Authentication. Its been vetted by security professionals and time, and<br />
is almost certainly more secure than some secret key you&#039;ve come up with. There are many varieties of Digest auth. The<br />
one most useful for RESTful web services uses an algorithm of &quot;MD5-sess&quot; and Quality of Protextion (qop) of &quot;auth&quot;. The<br />
MD5-sess algorithm allows for 3rd-party authentication services, and not requiring the server to maintain a plaintext<br />
copy of the users&#039; passwords. A qop of &quot;auth&quot; protects against chosen-plaintext cryptanalysis attacks, by having a<br />
counter incremented by the client, and a client-generated nonce. For a quick overview, Wikipedia has a <a href="http://en.wikipedia.org/wiki/Digest_access_authentication">good article</a>,<br />
and be sure to check out the spec, <a href="http://www.ietf.org/rfc/rfc2617.txt">RFC2617</a>. Here&#039;s a simple example to see whats going on. Client requests are<br />
denoted by <code>&gt;</code>, with server responses <code>&lt;</code>. This obviously isn&#039;t the whole content, just the interesting bits.</p>
<pre><code>&gt; GET /

&lt; HTTP/1.1 401 Authorization Required
&lt; WWW-Authenticate: Digest 
                    qop=&quot;auth&quot;, 
                    realm=&quot;My RESTful Application&quot;, 
                    opaque=&quot;55dd3242dd79740cefb67528b983bc8e&quot;, 
                    algorithm=MD5-sess, 
                    nonce=&quot;MjAwOS0wNy0xOSAyMDozMToyOToxODQ2NjA6MjAxZjRiMjVjZjRiYTc0MDEwNWIwY2U2NWIxMGNjNj&quot;

&gt; GET /
&gt; Authorization: Digest 
                 username=&quot;admin&quot;, 
                 qop=&quot;auth&quot;, 
                 realm=&quot;My RESTful Application&quot;, 
                 algorithm=&quot;MD5-sess&quot;,
                 opaque=&quot;55dd3242dd79740cefb67528b983bc8e&quot;, 
                 nonce=&quot;MjAwOS0wNy0xOSAyMDozMToyOToxODQ2NjA6MjAxZjRiMjVjZjRiYTc0MDEwNWIwY2U2NWIxMGNjNj&quot;, 
                 uri=&quot;/&quot;, 
                 nc=00000001, 
                 cnonce=&quot;Mjg5MDIz&quot;, 
                 response=&quot;1b8e5cdcd8d49ca65e3d6142567e44cf&quot;

&lt; HTTP/1.1 200 OK
&lt; Authentication-Info: qop=auth, 
                       nc=00000001, 
                       cnonce=&quot;Mjg5MDIz&quot;, 
                       nextnonce=00000002
</code></pre>
<p>Digest auth works when the client make an initial request without any authentication info. The server responds with a<br />
401, and provides a few parameters to the client in the <code>WWW-Authenticate</code> header. The <code>realm</code> is a string used to<br />
identify the application.  The client uses MD5 to hash together their <code>username</code>, the <code>realm</code> and their <code>password</code>.<br />
This is referred to as <code>HA1</code>. When the user was created, the server did the same, and <code>HA1</code> is what is stored in the<br />
database. </p>
<p>The client then generates a random string (the &quot;client nonce&quot; or <code>cnonce</code>) and increments a counter (&quot;nonce counter&quot; <code>nc</code>).<br />
It hashes method as an uppercase string (&quot;GET&quot;) and the URI (&quot;/&quot;) together to produce <code>HA2</code>. Finally, it hashes <code>HA1</code>,<br />
<code>HA2</code>, the <code>nonce</code>, <code>nc</code>, <code>cnonce</code>, and <code>qop</code> all together to arrive at <code>response</code>. It packages this all up into the<br />
<code>Authorization</code> header, and makes the request again. The server has all the information it needs (it stored the <code>HA1</code><br />
instead of the plaintext password) to hash the same parameters itself. If it arrives at the same <code>response</code>, then it<br />
knows the client knows the password for the user, and allows it to proceed.</p>
<p>Optionally, the server can provide an <code>Authentication-Info</code> header attached to the response. This provides enough<br />
information for the client to automatically authenticate for the next request, without having to get a 401 again.<br />
An alternative would be to just keep using the same <code>nonce</code> over and over, but this may be subject to replay attacks.<br />
The downside of this, though, is that the client cannot pipeline requests.</p>
<h2>Don&#039;t put the API version in the URI</h2>
<p>Several web services (including Tracker&#039;s) have uris that look like <code><a href="http://myapp.com/v1/projects" rel="nofollow">http://myapp.com/v1/projects</a></code> or<br />
<code><a href="http://myapp.com/projects?v=2" rel="nofollow">http://myapp.com/projects?v=2</a></code>. While this is perfectly RESTful, it seems a bit odd. From a pedantically REST-view,<br />
<code>/v1/projects/1234</code> and <code>/v2/projects/1234</code> are the locations of totally different resources, when, in fact, they are<br />
simply different <strong>representations</strong> of the same resource. From a more practical standpoint, say a client is written<br />
when only version one of a service is available, and it stores (&quot;bookmarks&quot;) some of these resources. Some time later,<br />
the application team decides they need to release some incompatible changes to their API, so they increment the version.<br />
Some time after that, the client upgrades to support the new version. However, the upgrade is not as clean as it might<br />
be, because they still have the saved locations pointing to the old version. The client either needs to support <em>both</em><br />
versions, or write a tool that does, so it can migrate the url to their new locations. They could munge the urls, but<br />
if one of the incompatible changes was going from integer ids to UUIDs, they have no choice.</p>
<p>Luckily, HTTP has a built-in solution to this problem: Content Negotiation. It makes use of two headers, <code>Accept</code> on<br />
the client side, and <code>Content-Type</code> on the server side. The Tracker services serve everything back with a <code>Content-Type</code><br />
of <code>application/xml</code>. Its not just any old XML, however, it is a specific form of XML, the schema of which is described<br />
in their API docs. This is the situation for which the use of mimetypes is intended. If every form of image out there<br />
just used a mime-type of <code>image</code>, we&#039;d have a much harder time of things. Luckily, there&#039;s more than that, with <code>image/gif</code>,<br />
<code>image/png</code>, and <code>image/jpeg</code>, which all represent different encodings of images. Following the same idea, Tracker could<br />
instead use something like <code>application/vnd.pivotal.tracker.v1+xml</code>. Yes, its still XML, but its Pivotal Tracker Version<br />
1 flavor of XML. Then when Pivotal decides its time for incompatible changes, they only have to add an additional content<br />
type, <code>application/vnd.pivotal.tracker.v2+xml</code>. </p>
<p>Following this idea, now a project always lives at <code>/projects/1234</code>. This is better, because while <code>v1</code> and <code>v2</code> of a<br />
project probably aren&#039;t different, their representations are. When a client updates versions, their links don&#039;t break,<br />
nor do they have to support two or more versions. </p>
<p>I&#039;ve only just brushed the surface of this topic. For more, <a href="http://barelyenough.org">Peter Williams</a> has an excellent discussion of it<br />
<a href="http://barelyenough.org/blog/2008/05/versioning-rest-web-services/">here</a>, <a href="http://barelyenough.org/blog/2008/05/versioning-rest-web-services-tricks-and-tips/">here</a>, and <a href="http://barelyenough.org/blog/2008/05/resthttp-service-versioning-reponse-to-jean-jacques-dubray/">here</a>. (disclaimer &amp;emdash; Peter is a former coworker and<br />
personal friend. This section and his posts are about a solution we came up with for a project.) </p>
<h1>Now You Don&#039;t Have Any Excuses</h1>
<p>I hope that this post serves as a good description of why you shouldn&#039;t be designing web services the way every body<br />
else does. It seems that everyone is just copying everyone else, without really understanding the pros and cons of the<br />
implementations. I hope this sparks some discussion, because I don&#039;t know that these are even the best way to be doing<br />
it, I just know from the experience of writing both applications and consumers, they way everyone is doing it now is<br />
much more difficult than it needs to be.</p><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/166/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/166/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=166&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
		<item>
		<title>Writing DataMapper Adapters &#8211; A Tutorial</title>
		<link>http://blog.theamazingrando.com/2009/03/30/writing-datamapper-adapters-a-tutorial/</link>
		<pubDate>Mon, 30 Mar 2009 20:33:33 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=168</guid>
		<description><![CDATA[Writing DataMapper Adapters &#8211; A Tutorial Introduction The adapter API for DataMapper has been in a bit of flux recently. When I submitted my proposal for a talk at MountainWest, adapters were irritatingly complex to write. You just needed to know too much about DataMapper&#039;s internals to be able to write one. A week before [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=168&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>Writing DataMapper Adapters &#8211; A Tutorial</h1>
<h2>Introduction</h2>
<p>The adapter API for DataMapper has been in a bit of flux recently. When I submitted<br />
my proposal for a <a href="http://mwrc2009.confreaks.com/14-mar-2009-16-10-writing-adapters-for-datamapper-paul-sadauskas.html">talk at MountainWest</a>, adapters were irritatingly complex to write.<br />
You just needed to know too much about DataMapper&#039;s internals to be able to write one.<br />
A week before the conference began, I started a significant effort to re-write the API to make<br />
it easier. I succeeded, a little too well; my 30 minute talk only took 15. Since then,<br />
I&#039;ve written a couple more adapters from scratch, and refined the API further. This post<br />
will serve as notes on the changes that I&#039;ve made, and a tutorial on writing adapters.</p>
<p>The API changes are currently only in my branch, but they will be merged into the<br />
<a href="http://www.github.com/datamapper/dm-core/tree/next">DataMapper/next</a> branch. For now, you&#039;ll need to use my<br />
<a href="http://www.github.com/paul/dm-core/tree/adapters_1.0">adapters_1.0</a> branch.</p>
<p>This tutorial will follow my process as I make a DataMapper adapter for <a href="http://tokyocabinet.sourceforge.net/index.html">TokyoTyrant</a>. You<br />
can grab the code from my github repo, <a href="http://www.github.com/paul/dm-tokyotyrant-adapter">paul/dm-tokyotyrant-adapter</a>.</p>
<h2>Setup</h2>
<p>I&#039;ll assume you know how to build a gem, and get it all set up using your favorite gem builder,<br />
so I&#039;m going to skip all that. To begin, we only need a couple files. First (of course!), the spec:</p>
<h3>spec/dm-tokyotyrant-adapter_spec.rb</h3>
<pre><code>require File.dirname(__FILE__) + &#039;/spec_helper&#039;

require &#039;dm-core/spec/adapter_shared_spec&#039;

describe DataMapper::Adapters::TokyoTyrantAdapter do
  before :all do
    @adapter = DataMapper.setup(:default, :adapter   =&gt; &#039;tokyo_tyrant&#039;,
                                          :hostname  =&gt; &#039;localhost&#039;,
                                          :port      =&gt; 1978)
  end

  it_should_behave_like &#039;An Adapter&#039;

end
</code></pre>
<p>And thats all there is to it. We make an <code>@adapter</code> instance var, which gets returned from<br />
<code>DataMapper.setup</code>, and then run the adapter shared spec. As of now, the shared spec is fairly<br />
thorough, but its far from comprehensive. If we run this now, we&#039;ll get some errors about not finding<br />
the <code>TokyoTyrantAdapter</code>. So, lets go make it.</p>
<h2>Initialization</h2>
<h3>lib/dm-tokyotyrant-adapter.rb</h3>
<pre><code>require &#039;dm-core&#039;
require &#039;dm-core/adapters/abstract_adapter&#039;       # 1

require &#039;tokyotyrant&#039;

module DataMapper::Adapters

  class TokyoTyrantAdapter &lt; AbstractAdapter      # 2
    include TokyoTyrant

    def initialize(name, options)
      super                                       # 3

      @options[:hostname] ||= &#039;localhost&#039;         # 4
      @options[:port]     ||= 1978

      @db = RDB::new                              
    end
  end

end
</code></pre>
<p>Some of this is pretty TokyoTyrant-specific. Since the Ruby API isn&#039;t very Rubyish, I&#039;m going<br />
to skip over a lot of it, and just talk about the DataMapper/adapter specific stuff. Referencing<br />
the comments in the code above:</p>
<ol>
<li><code>require</code> the abstract adapter explicitly, since its not <code>require</code>&#039;d as part of requiring dm-core.</li>
<li>Make a class that follows the naming convention <code>#{AdapterName}Adapter</code> so that DataMapper can find it<br />
when we use the <code>:adapter =&gt; &#039;adapter_name&#039;</code> option. Inherit from AbstractAdapter as well, as it will<br />
provide us with many helpers we&#039;ll be using.</li>
<li>Make an <code>initialize</code> method, and call super. This will turn any provided options into a Mash (a Hash<br />
that can use a string and a symbol as the same key. It handles a little other setup for you, as well.</li>
<li>The rest is Tyrant-specific, but useful to know. We set some default connection options, and initialze<br />
a <code>@db</code> object.</li>
</ol>
<p>If we run the spec now, it connects, and we get a bunch of pending specs, saying we need to implment <code>#read</code>,<br />
<code>#create</code>, etc&#8230;</p>
<pre><code>dm-tokyotyrant-adapter/master % rake spec
(in /home/rando/dev/dm-tokyotyrant-adapter)
*****

Pending:

DataMapper::Adapters::TokyoTyrantAdapter needs to support #create (Not Yet Implemented)
/usr/lib/ruby/gems/1.8/gems/dm-core-0.10.0/lib/dm-core/spec/adapter_shared_spec.rb:52

DataMapper::Adapters::TokyoTyrantAdapter needs to support #read (Not Yet Implemented)
/usr/lib/ruby/gems/1.8/gems/dm-core-0.10.0/lib/dm-core/spec/adapter_shared_spec.rb:75

DataMapper::Adapters::TokyoTyrantAdapter needs to support #update (Not Yet Implemented)
/usr/lib/ruby/gems/1.8/gems/dm-core-0.10.0/lib/dm-core/spec/adapter_shared_spec.rb:107

DataMapper::Adapters::TokyoTyrantAdapter needs to support #delete (Not Yet Implemented)
/usr/lib/ruby/gems/1.8/gems/dm-core-0.10.0/lib/dm-core/spec/adapter_shared_spec.rb:129

DataMapper::Adapters::TokyoTyrantAdapter needs to support #read and #create to test query matching (Not Yet Implemented)
/usr/lib/ruby/gems/1.8/gems/dm-core-0.10.0/lib/dm-core/spec/adapter_shared_spec.rb:289

Finished in 0.005982 seconds

5 examples, 0 failures, 5 pending
</code></pre>
<h2>Create</h2>
<pre><code>def create(resources)                                     # 1
  db do |db|                                              # 2
    resources.each do |resource|                          # 3
      initialize_identity_field(resource, rand(2**32))    # 4
      save(db, key(resource), serialize(resource))        # 5
    end
  end
end
</code></pre>
<ol>
<li><code>resources</code> is an Array of DataMapper Resource objects.</li>
<li><code>#db</code> is a helper to make TokyoTyrant&#039;s api a little more friendly. It handles connecting to the<br />
ttserver, and yields the connection to the block. When finished, it closes the connetion.</li>
<li>Some adapters might be able to support bulk creates, like SQL INSERT. This one doesn&#039;t, so we&#039;ll loop<br />
over every resource.</li>
<li>We&#039;ll need to set the identity field. More on this later.</li>
<li>Put the resource into the database. <code>#key</code> and <code>#serialize</code> are helpers, I&#039;ll explain them in a bit.</li>
</ol>
<p>Something useful to note here: The resources being passed in to this method are the actual resources in use by DataMapper. That<br />
means that any modifications you make to them will also be automatically availble to anything using DataMapper. This is extremely<br />
useful for any data store that can provide a representation of the created object. If the data store set some fields as a result<br />
of creation, eg, a <code>created_at</code> timestamp, or an <code>href</code> linking to the location of the resource, you can update the resource right<br />
here, and not have to have DataMapper perform a <code>#read</code> to update the resource object.</p>
<p>If you&#039;re coming from an RDBMS world, you&#039;ll be familiar with sequences. Since you&#039;re here, learning how to write<br />
adapters, I&#039;m going to assume you&#039;re not going to be talking to a relational database. If thats the case, and you don&#039;t need<br />
to support these kinds of sequences, you should probably use UUIDs or something similar for your identity fields. Sequences are<br />
not scalable or distributable, they&#039;re a relic of the big RDBMSs. I only have this <code>#initialize_identity_field</code> line in there to<br />
show how its done. As you can see, I&#039;m not even picking it sequentially, but choosing a random number, instead, because I don&#039;t have<br />
a resonable way to keep track of sequences. The method won&#039;t try to overwrite a value if one is already set, so take the opportunity to<br />
use a UUID instead, and save everyone involved a bunch of trouble.%lt;/soapbox&gt;</p>
<p>Because TokyoCabinet &amp; Tyrant are key-value stores, I&#039;ve written a couple helpers to try and coerce resources into a single key and<br />
value. First, I choose a key from the model name, and keys in the model, like so:</p>
<pre><code>def key(resource)
  model = resource.model
  key = resource.key.join(&#039;/&#039;)
  &quot;#{model}/#{key}&quot;
end
</code></pre>
<p>We get the model, and the keys from the resource. One thing to keep in mind, is that DataMapper assumes composite keys for every model,<br />
so even if a model has only a single key, <code>Resource#keys</code> will always return an array. We use that to build a string, like<br />
<code>Article/1234</code>. I chose a slash as the delimiter, because TokyoTyrant has a ReSTful interface, and it will make for pretty urls.</p>
<p>We also need to serialze the resource. I chose to serialize it as JSON, because its cross-platform, and lightweight. YAML or even XML would<br />
also be ok choices, depending on what you may be interoperating with.</p>
<pre><code>def serialize(resource)
  resource.attributes(:field).to_json
end
</code></pre>
<p><code>resource#attributes</code> normally returns a Hash of <code>{:property_name =&gt; value}</code> pairs. DataMapper properties also can take an option, <code>:field</code>,<br />
which is used to indicate the name of the field used by the data store. Because we&#039;re writing an adapter to a data-store, thats what we want.<br />
<code>#attributes</code> can take an optional argument to indicate what we want to use as keys. Here, I used <code>:field</code>, meaning I want the field attribute<br />
of the property. It will then return a Hash of the form <code>{&quot;field_name&quot; =&gt; value}</code> There usually won&#039;t be a difference, but its important<br />
that adapters use the field instead of the name, so that someone writing a model can use the <code>:field</code> option to property correctly.</p>
<p>Let&#039;s run the spec again, and see how we did:</p>
<pre><code>dm-tokyotyrant-adapter/master % rake spec
(in /home/rando/dev/dm-tokyotyrant-adapter)
/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake/gempackagetask.rb:13:Warning: Gem::manage_gems is deprecated and will be removed on or after March 2009.
****..

Finished in 0.009957 seconds

6 examples, 0 failures, 4 pending
</code></pre>
<h2>Read</h2>
<pre><code>def read(query)
  model = query.model

  db do |db|
    keys = db.fwmkeys(model.to_s)
    records = []
    keys.each do |key|
      value = db.get(key)
      records &lt;&lt; deserialize(value) if value
    end
    filter_records(records, query)
  end
end
</code></pre>
<p><code>#read</code> takes a DataMapper::Query object, which has everything needed to filter, sort, and limit records. For simple adapters, that don&#039;t have<br />
a native query language, you don&#039;t need to care. The <code>#filter_records</code> helper in AbstractAdapter will take care of everything for you. All you<br />
need to do it provide it an Array of Hashes, using the <code>field</code> name of the property as the key. Since we use json to serialize the value, here<br />
we deserialize it back into a hash. We used field names as the keys, so no further translation is needed. TokyoTyrant provides the <code>#fwmkeys</code><br />
method as a way to search for a key prefix, so we pass the model name in, because the model name is the first part of the key we used. We pass<br />
all the records we found in to <code>#filter_records</code>, which performs the filtering, and we then return the result.</p>
<h2>Update </h2>
<pre><code>def update(attributes, collection)                                 # 1
  attributes = attributes_as_fields(attributes)                    # 2
  db do |db|
    collection.each do |resource|                                  # 3
      attributes = resource.attributes(:field).merge(attributes)   # 4
      save(db, key(resource), serialize(resource))                 # 5
    end
  end
end
</code></pre>
<ol>
<li>We take an <code>attributes</code> hash and a DataMapper::Collection. The <code>attributes</code> are in the form of <code>{Property =&gt; value}</code>, using the actual<br />
property object. A <code>Collection</code> is a set of resources. </li>
<li>We need to convert the keys in the <code>attributes</code> has from <code>Property</code> objects into <code>:field</code> name. Luckily, AbstractAdapter provides<br />
<code>#attributes_as_fields</code>, which does exactly that.</li>
<li>Iterate over every resource in the collection</li>
<li>Update the attributes hash with the combination of the existing attributes, merged with the attributes we wish to update.</li>
<li>Write the whole thing back to the database.</li>
</ol>
<p>You may also want to take a look at how the <a href="http://github.com/paul/dm-core/blob/27a0277c8b00aa9d5be67a25a4113c437e4a6b34/lib/dm-core/adapters/in_memory_adapter.rb">InMemoryAdapter in dm-core</a> accomplishes the same task. It extracts the query<br />
used to build the collection, and looks for those records in its data store, using <code>#filter_records</code>. It then updates each record in-place.<br />
Either way works fine, and the ease of which may depend upon the adapter. In TokyoTyrant, finding the records is harder than retrieving them,<br />
so I opted to just re-save the ones I already had in the collection. An SQL adapter is able to update the records without loading them, so<br />
using the query is faster. ( &quot;UPDATE {attributes} WHERE {query}&quot; ).</p>
<h2>Delete</h2>
<pre><code>def delete(collection)
  db do |db|
    collection.each do |resource|
      db.delete(key(resource))
    end
  end
end
</code></pre>
<p>At this point, it should all be self-explainatory. Just iterate over every resource in the colleciton, and delete its key from the db. Yay.</p>
<h2>Conclusion</h2>
<p>And thats all there is to it. 3 hours, 2 beers, and ~100 LOC later, and we have a fully-capable adapter that can be used with DataMapper. I was<br />
running the specs at every stage, but left them out for brevity. Here&#039;s the final run:</p>
<pre><code>dm-tokyotyrant-adapter/master % rake spec
(in /home/rando/dev/dm-tokyotyrant-adapter)
......................................

Finished in 0.175668 seconds

38 examples, 0 failures
</code></pre>
<p>As I said before, the specs aren&#039;t exactly comprehensive, but they will be added to over the next few weeks. For now, they&#039;re good enough that you<br />
can be pretty confident your adapter will work for most things.</p>
<p>Thanks for tuning in, leave a comment, or come visit me in #datamapper on freenode if you have any adapter questions.</p><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/168/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/168/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=168&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
		<item>
		<title>I spoke at Mountain West!</title>
		<link>http://blog.theamazingrando.com/2009/03/24/i-spoke-at-mountain-west/</link>
		<pubDate>Tue, 24 Mar 2009 00:44:50 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=170</guid>
		<description><![CDATA[I spoke at Mountain West! Confreaks posted my talk. Everyone go make fun of that huge nerd up there! http://mwrc2009.confreaks.com/player.swf I pushed some of the changes I talked about to my github branch. This covers the Conditions objects. Next on my personal roadmap for adapters one-point-oh edition are for Repository to handle turning the responses [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=170&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>I spoke at Mountain West!</h1>
<p>Confreaks posted my talk. Everyone go make fun of that huge nerd up there!</p>
<p><a href="http://mwrc2009.confreaks.com/player.swf">http://mwrc2009.confreaks.com/player.swf</a></p>
<p>I pushed some of the changes I talked about to my <a href="http://github.com/paul/dm-core/tree/conditions">github branch</a>. This covers the Conditions objects.</p>
<p>Next on my personal roadmap for adapters one-point-oh edition are for Repository to handle turning the responses from adapters into Resource objects, if they aren&#039;t already.</p><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/170/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/170/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=170&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
		<item>
		<title>DataMapper Echo Adapter</title>
		<link>http://blog.theamazingrando.com/2009/03/11/datamapper-echo-adapter/</link>
		<pubDate>Wed, 11 Mar 2009 18:45:41 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=172</guid>
		<description><![CDATA[DataMapper Echo Adapter I just wrote a simple adapter that can be used to investigate the DM Adapter API, and debug your own adapter. Its really simple to use: DataMapper.setup(:default, :adapter =&#62; :echo, :echo =&#62; {:adapter =&#62; :in_memory}) Set the :echo option to and options hash or connection uri that can initialize the adapter you [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=172&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>DataMapper Echo Adapter</h1>
<p>I just wrote a simple adapter that can be used to investigate the DM Adapter API, and debug your own adapter. Its really simple to use:</p>
<pre><code>DataMapper.setup(:default, 
                 :adapter =&gt; :echo, 
                 :echo =&gt; {:adapter =&gt; :in_memory})
</code></pre>
<p>Set the <code>:echo</code> option to and options hash or connection uri that can initialize the adapter you want to wrap. This will print out the method calls, arguments, and return values to STDOUT.</p>
<pre><code>#read
query: #&lt;DataMapper::Query @repository=:default 
                           @model=Article 
                           @fields=[#&lt;DataMapper::Property @model=Article @name=:id&gt;, 
                                    #&lt;DataMapper::Property @model=Article @name=:title&gt;] 
                           @links=[] @conditions=[] @order=[] @limit=nil @offset=0 
                           @reload=false @unique=false&gt;
 # =&gt; [#&lt;Article @id=1 @title=&quot;Test&quot; @text=&lt;not loaded&gt;&gt;]
</code></pre>
<p><a href="http://github.com/paul/dm-echo-adapter/tree/master">Its on github</a><br />
<a href="http://gist.github.com/77614">Example output</a></p><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/172/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/172/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=172&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
		<item>
		<title>A Response to &#8220;Database Versioning&#8221;</title>
		<link>http://blog.theamazingrando.com/2009/03/02/a-response-to-database-versioning/</link>
		<pubDate>Mon, 02 Mar 2009 19:36:50 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">https://theamazingrand0.wordpress.com/?p=174</guid>
		<description><![CDATA[A Response to &#34;Database Versioning&#34; I was just going to post a comment in reply to Adam Wiggins&#039;s Database Versioning post, but it ended up being pretty long, so I&#039;ll post a response here instead. I&#039;m the original author and current maintainer of the migrations plugin for datamapper. I spent a lot of time thinking [&#8230;]<img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=174&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>A Response to &quot;Database Versioning&quot;</h1>
<p>I was just going to post a comment in reply to <a href="http://adam.blog.heroku.com/past/2009/3/2/database_versioning/">Adam Wiggins&#039;s Database Versioning post</a>, but it ended up being pretty long, so I&#039;ll post a response here instead.</p>
<p>I&#039;m the original author and current maintainer of the migrations plugin for datamapper. I spent a lot of time <a href="http://www.theamazingrando.com/blog/?p=11">thinking about AR migrations</a> before I started writing it. I think that DM migrations have solved a few of the problems he has with AR migrations.</p>
<p>The part about screwing up a migration, and having to re-run it sounds more like a tooling problem. When I write a migration, I drop/create the db, and re-run all the migrations to &#039;test&#039; it. (Also, the <a href="http://www.theamazingrando.com/blog/?p=21">DM migration specs</a> should help with this.) Yeah, it blows away all your development data, but you should have fixtures or scripts or something to make it easy to recreate. </p>
<p>There are also long-term plans for a plugin in datamapper to inspect the current database schema, examine the definitions in the models, then &quot;infer&quot; the migration that needs to take place. It will be impossible, of course, to guess at what kind of data migration might be needed, but I believe that migrations shouldn&#039;t touch data. If, given your fullname =&gt; firstname, lastname example, I add the new columns, and run a rake task to handle the data. After a few days/weeks, when I&#039;m sure that every production server has been upgraded, and that task run, I&#039;ll write a migration to drop the fullname column.</p>
<p>I do agree that having the database schema living in two different places if very non-dry, but even his suggestion of a schema.yml would duplicate the column definitions that are present in datamapper models.So </p>
<p>I&#039;ve used these DM migrations in 2 projects now that have been in production for &gt;6 months, and it fits in very well with my workflow. I tend to break up the migration files by table, so I end up with <code>schema/people.rb</code>, <code>schema/articles.rb</code>, <code>schema/comments.rb</code>, with each of those being a table in the db. Then inside one of the files, I list the migrations in version order: <code>1, :create_people_table</code>, <code>2, :add_firstname_lastname</code>, <code>3, :remove_fullname</code>. This lets me see at a glance what version I&#039;m on for a particular table, and I don&#039;t have to worry about dependencies. If I do need to modify several tables at once, I have a simple rake task that tells me what the maximum version number is, so I can make one after it.</p>
<p>I think that tryring to use SHAs as version numbers would be even more annoying than epoch timestamps as versions. I do like the idea about the model/application requiring a specific version, and refusing to start otherwise. From a DataMapper POV, it would be easy to add a <code>#requires_db_version(5)</code> method to the model. I&#039;m already in the habit of not using my models in migrations, by virtue of never writing data migrations. I even just usually write the migrations in raw SQL, it gives me more control over the table stucture when I really care.</p>
<p>So, essentially, DataMapper already provides the solution that Adam outlines in his post; Replace schema.yml with DataMapper model definitions, and have the discipline to not write data migrations. Write specs for your migrations, like everything else, and use DM migrations&#039; sane versioning, rather than AR&#039;s irritating one, and you should be fine. There are definitely improvements to be made with DM migrations, to be sure, but I feel like I got the underlying design mostly right.</p><br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/theamazingrand0.wordpress.com/174/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/theamazingrand0.wordpress.com/174/" /></a> <img alt="" border="0" src="http://pixel.wp.com/b.gif?host=blog.theamazingrando.com&#038;blog=527012&#038;post=174&#038;subd=theamazingrand0&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
		
		<media:content url="http://1.gravatar.com/avatar/498ea01ee88beecb59be73ea42c1f3c6?s=96&#38;d=identicon" medium="image">
			<media:title type="html">admin</media:title>
		</media:content>
	</item>
	</channel>
</rss>
