<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Groovie: Routes 1.4 Release and Web Services</title>
    <link>http://groovie.org/articles/2006/08/02/routes-1-4-release-and-web-services</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Code, Thoughts, and Misc Debris</description>
    <item>
      <title>Routes 1.4 Release and Web Services</title>
      <description>&lt;p&gt;This is slightly old as &lt;a href="http://routes.groovie.org/"&gt;Routes&lt;/a&gt; 1.4 was released about a week and a half ago, but I thought it deserved some attention. There were a handful of fixes and some slightly major feature enhancements in 1.4.&lt;/p&gt;


	&lt;p&gt;From the changelog:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Fixed bug with map.resource related to member methods, found in Rails version.&lt;/li&gt;
		&lt;li&gt;Fixed bug with map.resource member methods not requiring a member id.&lt;/li&gt;
		&lt;li&gt;Fixed bug related to handling keyword argument controller.&lt;/li&gt;
		&lt;li&gt;Added map.resource command which can automatically generate a batch of routes
  intended to be used in a &lt;span class="caps"&gt;REST&lt;/span&gt;-ful manner by a web framework.&lt;/li&gt;
		&lt;li&gt;Added &lt;span class="caps"&gt;URL&lt;/span&gt; generation handling for a &amp;#8216;method&amp;#8217; argument. If &amp;#8216;method&amp;#8217; is specified, it
  is not dropped and will be changed to &amp;#8216;_method&amp;#8217; for use by the framework.&lt;/li&gt;
		&lt;li&gt;Added conditions option to map.connect. Accepts a dict with optional keyword args
  &amp;#8216;method&amp;#8217; or &amp;#8216;function&amp;#8217;. Method is a list of &lt;span class="caps"&gt;HTTP&lt;/span&gt; methods that are valid for the route.
  Function is a function that will be called with environ, matchdict where matchdict is
  the dict created by the &lt;span class="caps"&gt;URL&lt;/span&gt; match.&lt;/li&gt;
		&lt;li&gt;Fixed redirect_to function for using absolute &lt;span class="caps"&gt;URL&lt;/span&gt;&amp;#8217;s. redirect_to now passes all
  args to url_for, then passes the resulting &lt;span class="caps"&gt;URL&lt;/span&gt; to the redirect function. Reported
  by climbus.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h4&gt;Web Resources&lt;/h4&gt;


	&lt;p&gt;The map.resource command is based directly off the &lt;a href="http://plugins.radrails.org/directory/show/69"&gt;Simply Restful&lt;/a&gt; Rails plugin which adds support for various verb-oriented controller actions in a &lt;a href="http://www.xml.com/pub/a/2004/12/01/restful-web.html"&gt;RESTful service&lt;/a&gt; style approach. The Simply Restful layout is more or less the exact service style laid out in the &lt;a href="http://bitworking.org/projects/atom/draft-ietf-atompub-protocol-09.html"&gt;Atom Publishing Protocol&lt;/a&gt;.&lt;/p&gt;


It&amp;#8217;s a great approach and it also meant providing a few other features to Routes that I hadn&amp;#8217;t implemented previously, the most important being able to limit matching of a &lt;span class="caps"&gt;URL&lt;/span&gt; based on the &lt;span class="caps"&gt;HTTP&lt;/span&gt; method used. This is present in the new conditions clause for a Route:
&lt;pre&gt;&lt;code&gt;
map.connect('user/:id', controller='user', action='edit', 
    conditions={'method', ['GET', 'HEAD']})
map.connect('user/:id', controller='user', action='update',
    conditions={'method', ['PUT']})
&lt;/code&gt;&lt;/pre&gt;

The conditions clause can also accept your own function should you want to restrict the route to matching based off some other criteria (sub-domain, IP address, etc).
&lt;pre&gt;&lt;code&gt;
def stop_comcast(environ, match):
    if 'comcast.net' in environ['REMOTE_HOST']:
        return False
    return True

map.connect(':controller/:action/:id', conditions={'function':stop_comcast})
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;a href="http://loudthinking.com/"&gt;David Heinemeier Hansson&lt;/a&gt; recently posted an &lt;a href="http://www.loudthinking.com/arc/000593.html"&gt;entry about Resources on Rails&lt;/a&gt; discussing how important web services are. The other key point was to make it easier to write controllers that could not only give you easy browser access to your resources, but provide a web service &lt;span class="caps"&gt;API&lt;/span&gt; as well.&lt;/p&gt;


The two snippets shown above give you an &lt;code&gt;edit&lt;/code&gt; and &lt;code&gt;update&lt;/code&gt; capability that restricts matching based off the &lt;span class="caps"&gt;HTTP&lt;/span&gt; method (verb). Writing a huge mess of those for the rest of the functions needed for a full web service &lt;span class="caps"&gt;API&lt;/span&gt; like Atom is a bit of busy-body work, so in the opinionated style of Rails a single command wraps up the whole thing. In Routes it looks like this:
&lt;pre&gt;&lt;code&gt;
map.resource('user')
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;That will make the two routes at the top of this entry in addition to routes that handle &lt;span class="caps"&gt;PUT&lt;/span&gt;, and &lt;span class="caps"&gt;DELETE&lt;/span&gt;. It maps them out to a set of actions in the controller, and provides the capability to easily add more methods for specific verbs.&lt;/p&gt;


	&lt;p&gt;The &lt;code&gt;map.resource&lt;/code&gt; command is still getting tuned up, and we&amp;#8217;re integrating the additional functionality it provides back into &lt;a href="http://pylonshq.com/"&gt;Pylons&lt;/a&gt; as well. Josh Triplett also wrote some Python code that will parse &lt;span class="caps"&gt;HTTP&lt;/span&gt; Accept headers fully so that we can add some nice functionality to use in the controller to return the appropriate data given what the client is expecting (HTML, &lt;span class="caps"&gt;XML&lt;/span&gt;, JSON, etc.)&lt;/p&gt;


	&lt;p&gt;If you&amp;#8217;re using a Python web framework that doesn&amp;#8217;t use Routes&amp;#8230; maybe its time to put a request in. :)&lt;/p&gt;</description>
      <pubDate>Wed, 02 Aug 2006 10:26:00 -0700</pubDate>
      <guid isPermaLink="false">urn:uuid:2e4b09e4-489d-4899-b4a5-f283b50d6188</guid>
      <author>ben</author>
      <link>http://groovie.org/articles/2006/08/02/routes-1-4-release-and-web-services</link>
      <category>Code</category>
      <category>Python</category>
      <category>Rails</category>
      <category>Routes</category>
    </item>
  </channel>
</rss>
