|
1 | 1 | require 'forwardable'
|
2 | 2 |
|
3 | 3 | module Hyperclient
|
| 4 | + # Public: Exception that is raised when passing in invalid representation data |
| 5 | + # for the resource. |
| 6 | + class InvalidRepresentationError < ArgumentError |
| 7 | + attr_reader :representation |
| 8 | + |
| 9 | + def initialize(error_description, representation) |
| 10 | + super(error_description) |
| 11 | + @representation = representation |
| 12 | + end |
| 13 | + end |
| 14 | + |
4 | 15 | # Public: Represents a resource from your API. Its responsability is to
|
5 | 16 | # ease the way you access its attributes, links and embedded resources.
|
6 | 17 | class Resource
|
@@ -29,8 +40,9 @@ class Resource
|
29 | 40 | # representation - The hash with the HAL representation of the Resource.
|
30 | 41 | # entry_point - The EntryPoint object to inject the configutation.
|
31 | 42 | def initialize(representation, entry_point, response = nil)
|
32 |
| - representation = representation ? representation.dup : {} |
| 43 | + representation = validate(representation) |
33 | 44 | links = representation['_links'] || {}
|
| 45 | + |
34 | 46 | @_links = LinkCollection.new(links, links['curies'], entry_point)
|
35 | 47 | @_embedded = ResourceCollection.new(representation['_embedded'], entry_point)
|
36 | 48 | @_attributes = Attributes.new(representation)
|
@@ -68,6 +80,21 @@ def fetch(key, *args)
|
68 | 80 |
|
69 | 81 | private
|
70 | 82 |
|
| 83 | + # Internal: Ensures the received representation is a valid Hash-lookalike. |
| 84 | + def validate(representation) |
| 85 | + return {} unless representation |
| 86 | + |
| 87 | + if representation.respond_to?(:to_hash) |
| 88 | + representation.to_hash.dup |
| 89 | + else |
| 90 | + raise InvalidRepresentationError.new( |
| 91 | + "Invalid representation for resource (got #{representation.class}, expected Hash). " \ |
| 92 | + "Is your web server returning JSON HAL data with a 'Content-Type: application/hal+json' header?", |
| 93 | + representation |
| 94 | + ) |
| 95 | + end |
| 96 | + end |
| 97 | + |
71 | 98 | # Internal: Returns the self Link of the Resource. Used to handle the HTTP
|
72 | 99 | # methods.
|
73 | 100 | def _self_link
|
|
0 commit comments