Class: HyperResource::Link

Inherits:
Object
  • Object
show all
Includes:
Modules::HTTP
Defined in:
lib/hyper_resource/link.rb

Overview

HyperResource::Link is an object to represent a hyperlink and its URL or body parameters, and to encapsulate HTTP calls involving this link. Links are typically created by HyperResource, not by end users.

HTTP method calls return the response as a HyperResource (or subclass) object. Calling an unrecognized method on a link will automatically load the resource pointed to by this link, and repeat the method call on the resource object.

A HyperResource::Link requires the resource it is based upon to remain in scope. In practice this is rarely a problem, as links are almost always accessed through the resource object.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Modules::HTTP

#create, #delete, #delete_response, #get, #get_response, #patch, #patch_response, #post, #post_response, #put, #put_response, #update

Constructor Details

#initialize(resource, link_spec = {}) ⇒ Link

Returns a link based on the given resource and link specification hash. ‘link_spec` keys are: `href` (string, required), `templated` (boolean), `params` (hash), and `default_method` (string, default `“get”`).



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/hyper_resource/link.rb', line 45

def initialize(resource, link_spec={})
  unless link_spec.kind_of?(Hash)
    raise ArgumentError, "link_spec must be a Hash (got #{link_spec.inspect})"
  end
  link_spec = Hash[ link_spec.map{|(k,v)| [k.to_s, v]} ] ## stringify keys

  self.resource = resource
  self.base_href = link_spec['href']
  self.name = link_spec['name']
  self.templated = !!link_spec['templated']
  self.params = link_spec['params'] || {}
  self.default_method = link_spec['method'] || 'get'
  @headers = link_spec['headers'] || {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

Unrecognized methods invoke an implicit load of the resource pointed to by this link. The method call is then repeated on the returned resource.



116
117
118
# File 'lib/hyper_resource/link.rb', line 116

def method_missing(method, *args)
  self.send(default_method || :get).send(method, *args)
end

Instance Attribute Details

#base_hrefObject

The literal href of this link; may be templated.



24
25
26
# File 'lib/hyper_resource/link.rb', line 24

def base_href
  @base_href
end

#default_methodObject

Default HTTP method for implicit loading.



36
37
38
# File 'lib/hyper_resource/link.rb', line 36

def default_method
  @default_method
end

#nameObject

An optional name describing this link.



27
28
29
# File 'lib/hyper_resource/link.rb', line 27

def name
  @name
end

#paramsObject

A hash of URL or request body parameters.



33
34
35
# File 'lib/hyper_resource/link.rb', line 33

def params
  @params
end

#resourceObject

The resource from which this link originates.



39
40
41
# File 'lib/hyper_resource/link.rb', line 39

def resource
  @resource
end

#templatedObject

‘true` if this link’s href is a URI Template, ‘false` otherwise.



30
31
32
# File 'lib/hyper_resource/link.rb', line 30

def templated
  @templated
end

Instance Method Details

#headers(*args) ⇒ Object

When called with a hash, returns a new scope with the given headers; that is, returns a copy of itself with the given headers applied. These headers will be merged with ‘resource.headers` at request time.

When called with no arguments, returns the headers for this link.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/hyper_resource/link.rb', line 98

def headers(*args)
  if args.count == 0
    @headers
  else
    self.class.new(self.resource,
                   'href' => self.base_href,
                   'name' => self.name,
                   'templated' => self.templated,
                   'params' => self.params,
                   'method' => self.default_method,
                   'headers' => @headers.merge(args[0]))

  end
end

#hrefObject

Returns this link’s href, applying any URI template params.



61
62
63
64
65
66
67
68
# File 'lib/hyper_resource/link.rb', line 61

def href
  if self.templated
    filtered_params = self.resource.outgoing_uri_filter(params)
    URITemplate.new(self.base_href).expand(filtered_params)
  else
    self.base_href
  end
end

#urlObject

Returns this link’s fully resolved URL, or nil if ‘resource.root` or `href` are malformed.



72
73
74
75
76
77
78
# File 'lib/hyper_resource/link.rb', line 72

def url
  begin
    URI.join(self.resource.root, self.href.to_s).to_s
  rescue StandardError
    nil
  end
end

#where(params) ⇒ Object

Returns a new scope with the given params; that is, returns a copy of itself with the given params applied.



82
83
84
85
86
87
88
89
90
91
# File 'lib/hyper_resource/link.rb', line 82

def where(params)
  params = Hash[ params.map{|(k,v)| [k.to_s, v]} ]
  self.class.new(self.resource,
                 'href' => self.base_href,
                 'name' => self.name,
                 'templated' => self.templated,
                 'params' => self.params.merge(params),
                 'method' => self.default_method,
                 'headers' => @headers)
end