path-to README

Model web apps easily and access them via nice app-specific Ruby APIs.

Note to reader: You are invited to comment on the roadmap at positiveincline.com/?p=213

Description

path-to allows web applications to be modelled via URI templates and then accessed through an application-specific Ruby API. It is designed to be extended easily to support discovery mechanisms; included is an implementation based on the resource templates of described_routes.

Synopsis

Automatic configuration with described_routes

Create a client application configured from a server that supports described_routes:

require 'path-to/described_routes'

app = PathTo::DescribedRoutes::Application.new(:json => Net::HTTP.get(URI.parse("http://example.com/described_routes.json")))

app.users["dojo"].articles.recent
#=> http://example.com/users/dojo/articles/recent
app.users["dojo"].articles.recent.get
#=> "<html>...</html>"

app.users["dojo"].articles.recent["format" => "json"]
#=> http://example.com/users/dojo/articles/recent.json
app.users["dojo"].articles.recent.get
#=> [...]

See examples/delicious.rb for an example based on a partial YAML-based description of the Delicious API.

Local configuration

require "path-to"

class Users    < PathTo::Path ; end
class Articles < PathTo::Path ; end

app = Application.new(
    :users    => "http://example.com/users/{user}",
    :articles => "http://example.com/users/{user}/articles/{slug}") do |app|
  def app.child_class_for(instance, method, params)
    {
      :users    => Users,
      :articles => Articles
    }[method]
  end
end                                                         #=> Application

Note that the Users and Articles classes and the overridden #child_class_for method above can be done away with (reducing the above code to just four lines) if there is no need to define any class-specific behaviour.

Having defined URI template and class mappings for keys :users and :articles mapping to URI templates, calls to app.users and app.articles cause objects of the appropriate class to be generated. These in turn support chaining and the collection of request params, like this:

app.users                                                   #=> http://example.com/users/ <Users>
app.users(:user => "dojo")                                  #=> http://example.com/users/dojo <Users>
app.users[:user => "dojo"]                                  #=> http://example.com/users/dojo <Users>
app.articles(:user => "dojo", :slug => "my-article")        #=> http://example.com/users/dojo/articles/my-article <Articles>
app.users[:user => "dojo"].articles[:slug => "my-article"]  #=> http://example.com/users/dojo/articles/my-article <Articles>

With a little more work (overriding Users#[] and Articles#[] - as described in the documentation for the Path class), the last example becomes simply:

app.users["dojo"].articles["my-article"]                     #=> http://example.com/users/dojo/articles/my-article <Articles>

HTTP support comes courtesy of HTTParty (the Path class includes it). To GET an article in the above example, just invoke the get method on the path object:

app.users["dojo"].articles["my-article"].get                 #=> "<html>...</html>"

Installation

sudo gem install path-to

Author

Mike Burrows (asplake), email [email protected], website positiveincline.com (articles tagged path-to)