Class: PathTo::Application

Inherits:
WithParams show all
Defined in:
lib/path-to/application.rb

Overview

Provides a Ruby client API interface to a web application. Method calls on this Application object generate Path objects that map (via URI templates held here on the Application) to the web application’s URIs.

Example:

app = PathTo::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                                                         #=> PathTo::Application

app.users                                                   #=> http://example.com/users/ <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>

Instance Attribute Summary collapse

Attributes inherited from WithParams

#params, #parent, #service

Instance Method Summary collapse

Methods inherited from WithParams

#[], #child, #complete_params_hash!, #extract_params, #method_missing, #respond_to?

Constructor Details

#initialize(templates = {}, http_options = nil, default_type = Path, http_client = HTTPClient) {|_self| ... } ⇒ Application

Initializes an Application. Parameters:

templates

Initial value for the templates attribute, defaults to {}

http_options

Initial value for the http_options attribute, defaults to nil

default_type

Initial value for the default_type attribute, defaults to Path

http_client

An object through which http calls are invoked. See HTTPClient and Path#http_client.

Simple example:

# Model an application with just a "users" collection that generates Path objects
simple_app = PathTo::Application.new(:users => "http://example.com/users/{user}")

The constructor yields self, utilised in this example:

# Model an application with "users" and "articles" collections, represented here on the client side by Users and Articles objects   
bigger_app = PathTo::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

Yields:

  • (_self)

Yield Parameters:



68
69
70
71
72
# File 'lib/path-to/application.rb', line 68

def initialize(templates = {}, http_options = nil, default_type = Path, http_client = HTTPClient)
  super() # with default args
  @templates, @http_options, @default_type, @http_client = templates, http_options, default_type, http_client
  yield self if block_given?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class PathTo::WithParams

Instance Attribute Details

#default_typeObject (readonly)

A Class (or at least something with a #new method) from which child objects will be created



33
34
35
# File 'lib/path-to/application.rb', line 33

def default_type
  @default_type
end

#http_clientObject (readonly)

An HTTParty or similar



36
37
38
# File 'lib/path-to/application.rb', line 36

def http_client
  @http_client
end

#http_optionsObject (readonly)

Hash of options to be included in HTTP method calls



39
40
41
# File 'lib/path-to/application.rb', line 39

def http_options
  @http_options
end

#templatesObject (readonly)

A Hash that maps method keys (Symbol) to URI templates (String)



30
31
32
# File 'lib/path-to/application.rb', line 30

def templates
  @templates
end

Instance Method Details

#applicationObject

Returns self. See Path#application.



92
93
94
# File 'lib/path-to/application.rb', line 92

def application
  self
end

#child_class_for(instance, method, params) ⇒ Object

Determines whether this application &/or its child objects should respond to the given method, and if so returns a class from which a new child instance (typically Path or a subclass thereof) will be created. This implementation (easily overridden) returns #default_type if there is a URI template defined for the method.

Parameters:

instance

This application or (presumably) one of its child objects

method

The method invoked on the instance that has (presumably) been intercepted by instance#method_missing

params

The instance’s params



85
86
87
# File 'lib/path-to/application.rb', line 85

def child_class_for(instance, method, params)
  default_type if uri_template_for(method, params)
end

#uri_for(method, params = {}) ⇒ Object

Generates a URI, looking up a URI template (via #uri_template_for) and getting it formatted with the params.

– TODO Consider taking an instance as the first parameter, as #child_class_for does



117
118
119
120
121
122
123
# File 'lib/path-to/application.rb', line 117

def uri_for(method, params = {})
  # TODO it's a 1-line fix to Addressable to permit symbols (etc) as keys
  if (t = uri_template_for(method, params))
    string_keyed_params = params.keys.inject({}){|hash, key| hash[key.to_s] = params[key]; hash}
    Addressable::Template.new(t).expand(string_keyed_params).to_s
  end
end

#uri_template_for(method, params = {}) ⇒ Object

Returns a URI template for the given method and params. Parameters:

method

The method invoked on the instance that has (presumably) been intercepted by instance#method_missing

params

The instance’s params

This implementation returns a value from the #templates Hash, keyed by method (params is ignored).

– TODO Consider taking an instance as the first parameter, as #child_class_for does



107
108
109
# File 'lib/path-to/application.rb', line 107

def uri_template_for(method, params = {})
  templates[method]
end