Class: HalClient::Representation

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/hal_client/representation.rb

Overview

HAL representation of a single resource. Provides access to properties, links and embedded representations.

Constant Summary collapse

RESERVED_PROPERTIES =
['_links', '_embedded'].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Representation

Create a new Representation

options - name parameters :parsed_json - A hash structure representing a single HAL document. :href - The href of this representation. :hal_client - The HalClient instance to use when navigating.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/hal_client/representation.rb', line 39

def initialize(options)
  @raw = options[:parsed_json]
  @hal_client = options[:hal_client]
  @href = options[:href]

  (fail ArgumentError, "Either parsed_json or href must be provided") if
    @raw.nil? && @href.nil?

  (fail InvalidRepresentationError, "Invalid HAL representation: #{raw.inspect}") if
    @raw && ! hashish?(@raw)
end

Instance Attribute Details

#hal_client ⇒ Object (readonly)

Internal: Returns the HalClient used to retrieve this representation



328
329
330
# File 'lib/hal_client/representation.rb', line 328

def hal_client
  @hal_client
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



296
297
298
299
300
301
302
303
304
# File 'lib/hal_client/representation.rb', line 296

def ==(other)
  if href && other.respond_to?(:href)
    href == other.href
  elsif other.respond_to?(:raw)
    @raw == other.raw
  else
    false
  end
end

#[](name_or_rel) ⇒ Object

Returns the value of the specified property or representations of resources related via the specified link rel or nil

name_or_rel - The name of property or link rel of interest



152
153
154
155
# File 'lib/hal_client/representation.rb', line 152

def [](name_or_rel)
  item_key = name_or_rel
  fetch(item_key, nil)
end


188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/hal_client/representation.rb', line 188

def all_links
  result = Set.new
  base_url = Addressable::URI.parse(href || "")

  embedded_entries = flatten_section(raw.fetch("_embedded", {}))
  result.merge(embedded_entries.map do |entry|
    Link.new_from_embedded_entry(hash_entry: entry,
                                 hal_client: hal_client,
                                 curie_resolver: namespaces,
                                 base_url: base_url)
  end)

  link_entries = flatten_section(raw.fetch("_links", {}))
  result.merge(link_entries.map { |entry|
    Link.new_from_link_entry(hash_entry: entry,
                             hal_client: hal_client,
                             curie_resolver: namespaces,
                             base_url: base_url) })

  result
end

#as_enum ⇒ Object

Returns an Enumerable of the items in this collection resource if this is an rfc 6573 collection.

Raises HalClient::NotACollectionError if this is not a collection resource.



256
257
258
# File 'lib/hal_client/representation.rb', line 256

def as_enum
  Collection.new(self)
end

#fetch(name_or_rel, default = MISSING, &default_proc) ⇒ Object

Returns the value of the specified property or representations of resources related via the specified link rel or the specified default value.

name_or_rel - The name of property or link rel of interest default - an optional object that should be return if the specified property or link does not exist default_proc - an option proc that will be called with name to produce default value if the specified property or link does not exist

Raises KeyError if the specified property or link does not exist and no default nor default_proc is provided.



139
140
141
142
143
144
145
146
# File 'lib/hal_client/representation.rb', line 139

def fetch(name_or_rel, default=MISSING, &default_proc)
  item_key = name_or_rel
  default_proc ||= ->(_){default} if default != MISSING

  property(item_key) {
    related(item_key, &default_proc)
  }
end

#hash ⇒ Object



288
289
290
291
292
293
294
# File 'lib/hal_client/representation.rb', line 288

def hash
  if href
    href.hash
  else
    @raw.hash
  end
end

#href ⇒ Object

Returns the URL of the resource this representation represents.



119
120
121
122
123
124
# File 'lib/hal_client/representation.rb', line 119

def href
  @href ||= raw
          .fetch("_links",{})
          .fetch("self",{})
          .fetch("href",nil)
end

#patch(data, options = {}) ⇒ Object

Patchs a Representation or String to this resource. Causes this representation to be reloaded the next time it is used.

data - a String or an object that responds to #to_hal options - set of options to pass to HalClient#patch



78
79
80
81
82
# File 'lib/hal_client/representation.rb', line 78

def patch(data, options={})
  @hal_client.patch(href, data, options).tap do
    reset
  end
end

#post(data, options = {}) ⇒ Object

Posts a Representation or String to this resource. Causes this representation to be reloaded the next time it is used.

data - a String or an object that responds to #to_hal options - set of options to pass to HalClient#post



56
57
58
59
60
# File 'lib/hal_client/representation.rb', line 56

def post(data, options={})
  @hal_client.post(href, data, options).tap do
    reset
  end
end

#properties ⇒ Object

Returns a Hash including the key-value pairs of all the properties in the resource. It does not include HAL's reserved properties (_links and _embedded).



114
115
116
# File 'lib/hal_client/representation.rb', line 114

def properties
  raw.reject { |k, _| RESERVED_PROPERTIES.include? k }
end

#property(name, default = MISSING, &default_proc) ⇒ Object

Returns The value of the specified property or the specified default value.

name - The name of property of interest default - an optional object that should be return if the specified property does not exist default_proc - an option proc that will be called with name to produce default value if the specified property does not exist

Raises KeyError if the specified property does not exist and no default nor default_proc is provided.



105
106
107
108
109
# File 'lib/hal_client/representation.rb', line 105

def property(name, default=MISSING, &default_proc)
  default_proc ||= ->(_){ default} if default != MISSING

  raw.fetch(name.to_s, &default_proc)
end

#property?(name) ⇒ Boolean Also known as: has_property?

Returns true if this representation contains the specified property.

name - the name of the property to check

Returns:

  • (Boolean)


88
89
90
# File 'lib/hal_client/representation.rb', line 88

def property?(name)
  raw.key? name
end

#put(data, options = {}) ⇒ Object

Puts a Representation or String to this resource. Causes this representation to be reloaded the next time it is used.

data - a String or an object that responds to #to_hal options - set of options to pass to HalClient#put



67
68
69
70
71
# File 'lib/hal_client/representation.rb', line 67

def put(data, options={})
  @hal_client.put(href, data, options).tap do
    reset
  end
end

#raw ⇒ Object

Internal: Returns parsed json document



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/hal_client/representation.rb', line 308

def raw
  if @raw.nil? && @href
    (fail "unable to make requests due to missing hal client") unless hal_client

    response = hal_client.get(@href)

    unless response.is_a?(Representation)
      error_message = "Response body wasn't a valid HAL document:\n\n"
      error_message += response.body
      raise InvalidRepresentationError.new(error_message)
    end

    @raw ||= response.raw
  end

  @raw
end

Returns values of the href member of links and the URL of embedded representations related via the specified link rel. The only difference between this and #related_hrefs is that this method makes no attempt to expand templated links. For templated links the returned collection will include the template pattern as encoded in the HAL document.

link_rel - The link rel of interest default_proc - an option proc that will be called with name to produce default value if the specified property or link does not exist

Raises KeyError if the specified link does not exist and no default_proc is provided.



241
242
243
244
245
246
247
248
249
# File 'lib/hal_client/representation.rb', line 241

def raw_related_hrefs(link_rel, &default_proc)
  default_proc ||= NO_RELATED_RESOURCE

  embedded = embedded(link_rel) { nil }
  linked = links.hrefs(link_rel) { nil }
  return default_proc.call(link_rel) if embedded.nil? and linked.nil?

  Array(linked) + Array(embedded).map(&:href)
end

Returns representations of resources related via the specified link rel or the specified default value.

link_rel - The link rel of interest options - optional keys and values with which to expand any templated links that are encountered default_proc - an option proc that will be called with name to produce default value if the specified property or link does not exist

Raises KeyError if the specified link does not exist and no default_proc is provided.



178
179
180
181
182
183
184
185
186
# File 'lib/hal_client/representation.rb', line 178

def related(link_rel, options = {}, &default_proc)
  default_proc ||= NO_RELATED_RESOURCE

  embedded = embedded(link_rel) { nil }
  linked = linked(link_rel, options) { nil }
  return default_proc.call(link_rel) if embedded.nil? and linked.nil?

  RepresentationSet.new (Array(embedded) + Array(linked))
end

#related?(link_rel) ⇒ Boolean Also known as: has_related?

Returns true if this representation contains a link (including embedded links) whose rel is link_rel.

link_rel - The link rel of interest

Returns:

  • (Boolean)


161
162
163
# File 'lib/hal_client/representation.rb', line 161

def related?(link_rel)
  !!(linked(link_rel) { false } || embedded(link_rel) { false })
end

Returns urls of resources related via the specified link rel or the specified default value.

link_rel - The link rel of interest options - optional keys and values with which to expand any templated links that are encountered default_proc - an option proc that will be called with name to produce default value if the specified property or link does not exist

Raises KeyError if the specified link does not exist and no default_proc is provided.



222
223
224
225
# File 'lib/hal_client/representation.rb', line 222

def related_hrefs(link_rel, options={}, &default_proc)
  related(link_rel, options, &default_proc).
    map(&:href)
end

#reset ⇒ Object

Resets this representation such that it will be requested from the upstream on it's next use.



271
272
273
274
# File 'lib/hal_client/representation.rb', line 271

def reset
  @href = href # make sure we have the href
  @raw = nil
end

#to_enum(method = :each, *args, &blk) ⇒ Object

Returns an Enumerator of the items in the collection resource if this is an rfc 6573 collection.

Raises HalClient::NotACollectionError if this is not a collection resource.



265
266
267
# File 'lib/hal_client/representation.rb', line 265

def to_enum(method=:each, *args, &blk)
  as_enum.to_enum(method, *args, &blk)
end

#to_json ⇒ Object Also known as: to_hal

Returns the raw json representation of this representation



283
284
285
# File 'lib/hal_client/representation.rb', line 283

def to_json
  MultiJson.dump(raw)
end

#to_s ⇒ Object

Returns a short human readable description of this representation.



278
279
280
# File 'lib/hal_client/representation.rb', line 278

def to_s
  "#<" + self.class.name + ": " + (href || "ANONYMOUS")  + ">"
end