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.9.4'
VERSION_DATE =
'2015-11-18'

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 && attributes.has_key?(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 rescue nil
  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 ith 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



98
99
100
101
102
# File 'lib/hyper_resource/modules/http.rb', line 98

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

#deleteObject

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



77
78
79
# File 'lib/hyper_resource/modules/http.rb', line 77

def delete
  to_link.delete
end

#delete_responseObject

Performs a DELETE request to this resource's URL. Returns a Faraday::Response object representing the response.



83
84
85
# File 'lib/hyper_resource/modules/http.rb', line 83

def delete_response
  to_link.delete_response
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

#get_responseObject

Performs a GET request to this resource's URL, and returns a Faraday::Response object representing the response.



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

def get_response
  to_link.get_response
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.



63
64
65
# File 'lib/hyper_resource/modules/http.rb', line 63

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

#patch_response(*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 Faraday::Response object representing the response.



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

def patch_response(*args)
  self.to_link.patch_response(*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.



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

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

#post_response(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 Faraday::Response object representing the response.



41
42
43
# File 'lib/hyper_resource/modules/http.rb', line 41

def post_response(attrs=nil)
  to_link.post_response(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.



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

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

#put_response(*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 Faraday::Response object representing the response.



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

def put_response(*args)
  to_link.put_response(*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.



89
90
91
92
93
# File 'lib/hyper_resource/modules/http.rb', line 89

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

#update(*args) ⇒ Object



105
106
107
108
109
# File 'lib/hyper_resource/modules/http.rb', line 105

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