Class: HyperResource

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Modules::ConfigAttributes, Modules::DataType, Modules::Deprecations, Modules::InternalAttributes
Defined in:
lib/hyper_resource.rb,
lib/hyper_resource/link.rb,
lib/hyper_resource/links.rb,
lib/hyper_resource/adapter.rb,
lib/hyper_resource/objects.rb,
lib/hyper_resource/version.rb,
lib/hyper_resource/attributes.rb,
lib/hyper_resource/exceptions.rb,
lib/hyper_resource/modules/http.rb,
lib/hyper_resource/configuration.rb,
lib/hyper_resource/adapter/hal_json.rb,
lib/hyper_resource/modules/data_type.rb,
lib/hyper_resource/modules/deprecations.rb,
lib/hyper_resource/modules/config_attributes.rb

Overview

HyperResource is the main resource base class. Normally it will be used through subclassing, though it may also be used directly.

Defined Under Namespace

Modules: Modules Classes: Adapter, Attributes, ClientError, Configuration, Exception, Link, Links, Objects, ResponseError, ServerError

Constant Summary collapse

VERSION =
'0.1.0'
VERSION_DATE =
'2015-01-06'

Constants included from Modules::ConfigAttributes

Modules::ConfigAttributes::ATTRS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Modules::InternalAttributes

included

Methods included from Modules::Deprecations

#_hr_deprecate, #deserialized_response, included, #response_body, #response_object

Methods included from Modules::DataType

#get_data_type, #get_data_type_class, included

Methods included from Modules::ConfigAttributes

#adapter, #adapter=, #adapter_for_url, #auth, #auth=, #auth_for_url, #config, #default_attributes, #default_attributes=, #default_attributes_for_url, #faraday_options, #faraday_options=, #faraday_options_for_url, #headers, #headers=, #headers_for_url, #hr_config, #hr_config=, included, #namespace, #namespace=, #namespace_for_url

Constructor Details

#initialize(opts = {}) ⇒ HyperResource

Create a new HyperResource, given a hash of options. These options include:

root

The root URL of the resource.

auth

Authentication information. Currently only {basic: [‘key’, ‘secret’]} is supported.

namespace

Class or class name, into which resources should be instantiated.

headers

Headers to send along with requests for this resource (as well as its eventual child resources, if any).

faraday_options

Configuration passed to Faraday::Connection.initialize, such as {request: {timeout: 30}}.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/hyper_resource.rb', line 56

def initialize(opts={})
  self.root = opts[:root] if opts[:root]
  self.href = opts[:href] if opts[:href]

  self.hr_config = self.class.hr_config.clone

  self.adapter         = opts[:adapter]         if opts[:adapter]
  self.faraday_options = opts[:faraday_options] if opts[:faraday_options]
  self.auth            = opts[:auth]            if opts[:auth]

  self.headers = DEFAULT_HEADERS.
                   merge(self.class.headers || {}).
                   merge(opts[:headers]     || {})

  self.namespace = opts[:namespace] if opts[:namespace]
  if !self.namespace && self.class != HyperResource
    self.namespace = self.class.namespace || self.class.to_s
  end

  ## There's a little acrobatics in getting Attributes, Links, and Objects
  ## into the correct subclass.
  if self.class != HyperResource
    if self.class::Attributes == HyperResource::Attributes
      Object.module_eval(
        "class #{self.class}::Attributes < HyperResource::Attributes; end"
      )
    end
    if self.class::Links == HyperResource::Links
      Object.module_eval(
        "class #{self.class}::Links < HyperResource::Links; end"
      )
    end
    if self.class::Objects == HyperResource::Objects
      Object.module_eval(
        "class #{self.class}::Objects < HyperResource::Objects; end"
      )
    end
  end

  self.attributes = self.class::Attributes.new(self)
  self.links      = self.class::Links.new(self)
  self.objects    = self.class::Objects.new(self)
  self.loaded     = false
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

method_missing will load this resource if not yet loaded, then attempt to delegate to attributes, then objects, then links. Override with extreme care.

Raises:

  • (NoMethodError)


189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/hyper_resource.rb', line 189

def method_missing(method, *args)
  ## If not loaded, load and retry.
  unless loaded
    return self.get.send(method, *args)
  end


  ## Otherwise, try to match against attributes, then objects, then links.
  method = method.to_s
  if method[-1,1] == '='
    return attributes[method[0..-2]] = args.first if attributes[method[0..-2]]
  else
    return attributes[method] if attributes && attributes.has_key?(method.to_s)
    return objects[method] if objects && objects[method]
    if links && links[method]
      if args.count > 0
        return links[method].where(*args)
      else
        return links[method]
      end
    end
  end

  raise NoMethodError, "undefined method `#{method}' for #{self.inspect}"
end

Class Method Details

.new_from(args) ⇒ Object

Creates a new resource given args :link, :resource, :href, :response, :url, and :body. Either :link or (:resource and :href and :url) are required.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/hyper_resource.rb', line 106

def self.new_from(args)
  link = args[:link]
  resource = args[:resource] || link.resource
  href = args[:href] || link.href
  url = args[:url] || URI.join(resource.root, href || '')
  response = args[:response]
  body = args[:body] || {}

  old_rsrc = resource
  new_class = old_rsrc.get_data_type_class(:resource => old_rsrc,
                                           :link => link,
                                           :url => url,
                                           :response => response,
                                           :body => body)
  new_rsrc = new_class.new(:root => old_rsrc.root,
                           :href => href)
  new_rsrc.hr_config = old_rsrc.hr_config.clone
  new_rsrc.response = response
  new_rsrc.body = body
  new_rsrc.adapter.apply(body, new_rsrc)
  new_rsrc.loaded = true
  new_rsrc
end

.user_agentObject



232
233
234
# File 'lib/hyper_resource.rb', line 232

def self.user_agent # @private
  "HyperResource #{HyperResource::VERSION}"
end

Instance Method Details

#[](i) ⇒ Object

Returns the *i*th object in the first collection of objects embedded in this resource. Returns nil on failure.



172
173
174
175
# File 'lib/hyper_resource.rb', line 172

def [](i)
  get unless loaded
  self.objects.first[1][i] rescue nil
end

#changed?(*args) ⇒ Boolean

Returns true if one or more of this object’s attributes has been reassigned.

Returns:

  • (Boolean)


138
139
140
# File 'lib/hyper_resource.rb', line 138

def changed?(*args)
  attributes.changed?(*args)
end

#create(attrs) ⇒ Object



64
65
66
67
68
# File 'lib/hyper_resource/modules/http.rb', line 64

def create(attrs)
  _hr_deprecate('HyperResource#create is deprecated. Please use '+
                '#post instead.')
  to_link.post(attrs)
end

#delete(*args) ⇒ Object

Performs a DELETE request to this resource’s URL. Returns a new resource representing the response.



49
50
51
# File 'lib/hyper_resource/modules/http.rb', line 49

def delete(*args)
  to_link.delete(*args)
end

#each(&block) ⇒ Object

Iterates over the objects in the first collection of embedded objects in this resource.



179
180
181
182
# File 'lib/hyper_resource.rb', line 179

def each(&block)
  get unless loaded
  self.objects.first[1].each(&block) rescue nil
end

#getObject

Performs a GET request to this resource’s URL, and returns a new resource representing the response.



21
22
23
# File 'lib/hyper_resource/modules/http.rb', line 21

def get
  to_link.get
end

#incoming_body_filter(attr_hash) ⇒ Object

incoming_body_filter filters a hash of attribute keys and values on their way from a response body to a HyperResource. Override this in a subclass of HyperResource to implement filters on incoming data.



148
149
150
# File 'lib/hyper_resource.rb', line 148

def incoming_body_filter(attr_hash)
  attr_hash
end

#inspectObject



226
227
228
229
230
# File 'lib/hyper_resource.rb', line 226

def inspect # @private
  "#<#{self.class}:0x#{"%x" % self.object_id} @root=#{self.root.inspect} "+
  "@href=#{self.href.inspect} @loaded=#{self.loaded} "+
  "@namespace=#{self.namespace.inspect} ...>"
end

#new_from(args) ⇒ Object



131
132
133
# File 'lib/hyper_resource.rb', line 131

def new_from(args)
  self.class.new_from(args)
end

#outgoing_body_filter(attr_hash) ⇒ Object

outgoing_body_filter filters a hash of attribute keys and values on their way from a HyperResource to a request body. Override this in a subclass of HyperResource to implement filters on outgoing data.



155
156
157
# File 'lib/hyper_resource.rb', line 155

def outgoing_body_filter(attr_hash)
  attr_hash
end

#outgoing_uri_filter(attr_hash) ⇒ Object

outgoing_uri_filter filters a hash of attribute keys and values on their way from a HyperResource to a URL. Override this in a subclass of HyperResource to implement filters on outgoing URI parameters.



163
164
165
# File 'lib/hyper_resource.rb', line 163

def outgoing_uri_filter(attr_hash)
  attr_hash
end

#patch(*args) ⇒ Object

Performs a PATCH request to this resource’s URL, sending ‘attributes.changed_attributes` as a request body unless an `attrs` Hash is given. Returns a new resource representing the response.



43
44
45
# File 'lib/hyper_resource/modules/http.rb', line 43

def patch(*args)
  self.to_link.patch(*args)
end

#post(attrs = nil) ⇒ Object

Performs a POST request to this resource’s URL, sending all of ‘attributes` as a request body unless an `attrs` Hash is given. Returns a new resource representing the response.



28
29
30
# File 'lib/hyper_resource/modules/http.rb', line 28

def post(attrs=nil)
  to_link.post(attrs)
end

#put(*args) ⇒ Object

Performs a PUT request to this resource’s URL, sending all of ‘attributes` as a request body unless an `attrs` Hash is given. Returns a new resource representing the response.



35
36
37
# File 'lib/hyper_resource/modules/http.rb', line 35

def put(*args)
  to_link.put(*args)
end

#respond_to?(method, *args) ⇒ Boolean

respond_to? is patched to return true if method_missing would successfully delegate a method call to attributes, links, or objects.

Returns:

  • (Boolean)


218
219
220
221
222
223
# File 'lib/hyper_resource.rb', line 218

def respond_to?(method, *args)
  return true if self.links && self.links.respond_to?(method)
  return true if self.attributes && self.attributes.respond_to?(method)
  return true if self.objects && self.objects.respond_to?(method)
  super
end

Creates a Link representing this resource. Used for HTTP delegation.



55
56
57
58
59
# File 'lib/hyper_resource/modules/http.rb', line 55

def to_link(args={})
  self.class::Link.new(self,
                       :href => args[:href] || self.href,
                       :params => args[:params] || self.attributes)
end

#update(*args) ⇒ Object



71
72
73
74
75
# File 'lib/hyper_resource/modules/http.rb', line 71

def update(*args)
  _hr_deprecate('HyperResource#update is deprecated. Please use '+
                '#put or #patch instead.')
  to_link.put(*args)
end

#urlObject

Returns this resource’s fully qualified URL. Returns nil when ‘root` or `href` are malformed.



10
11
12
13
14
15
16
# File 'lib/hyper_resource/modules/http.rb', line 10

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

#user_agentObject



236
237
238
# File 'lib/hyper_resource.rb', line 236

def user_agent # @private
  self.class.user_agent
end