hyperclient 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +2 -0
- data/.rubocop_todo.yml +55 -0
- data/.travis.yml +2 -0
- data/CHANGELOG.md +33 -10
- data/CONTRIBUTING.md +117 -0
- data/Gemfile +2 -1
- data/Guardfile +6 -6
- data/LICENSE +2 -2
- data/README.md +138 -0
- data/Rakefile +5 -3
- data/UPGRADING.md +37 -0
- data/examples/splines_api.rb +22 -0
- data/features/steps/api_navigation.rb +8 -8
- data/features/steps/default_config.rb +6 -6
- data/features/support/api.rb +4 -4
- data/features/support/fixtures.rb +1 -1
- data/hyperclient.gemspec +9 -8
- data/lib/faraday/connection.rb +2 -2
- data/lib/hyperclient.rb +1 -1
- data/lib/hyperclient/attributes.rb +1 -1
- data/lib/hyperclient/collection.rb +3 -3
- data/lib/hyperclient/curie.rb +49 -0
- data/lib/hyperclient/entry_point.rb +6 -4
- data/lib/hyperclient/link.rb +70 -58
- data/lib/hyperclient/link_collection.rb +36 -11
- data/lib/hyperclient/resource.rb +49 -18
- data/lib/hyperclient/resource_collection.rb +2 -1
- data/lib/hyperclient/version.rb +1 -1
- data/test/fixtures/element.json +12 -1
- data/test/hyperclient/attributes_test.rb +2 -2
- data/test/hyperclient/collection_test.rb +6 -7
- data/test/hyperclient/curie_test.rb +34 -0
- data/test/hyperclient/entry_point_test.rb +3 -2
- data/test/hyperclient/link_collection_test.rb +26 -5
- data/test/hyperclient/link_test.rb +111 -86
- data/test/hyperclient/resource_collection_test.rb +2 -2
- data/test/hyperclient/resource_test.rb +67 -30
- data/test/test_helper.rb +2 -2
- metadata +54 -39
- data/Gemfile.lock +0 -112
- data/MIT-LICENSE +0 -20
- data/Readme.md +0 -180
- data/examples/cyberscore.rb +0 -76
- data/examples/hal_shop.rb +0 -53
- data/lib/faraday/request/digest_authentication.rb +0 -85
- data/test/faraday/digest_authentication_test.rb +0 -41
data/UPGRADING.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
Upgrading Hyperclient
|
2
|
+
=====================
|
3
|
+
|
4
|
+
### Upgrading to >= 0.5.0
|
5
|
+
|
6
|
+
#### Remove Navigational Elements
|
7
|
+
|
8
|
+
You can, but no longer need to invoke `links`, `embedded`, `expand`, `attributes` or `resource` in most cases. Simply remove them. Navigational structures like `key.embedded.key` can also be collapsed.
|
9
|
+
|
10
|
+
Here're a few examples:
|
11
|
+
|
12
|
+
Instead Of | Write This
|
13
|
+
----------------------------------------------- | -----------------------
|
14
|
+
`api.links.widgets` | `api.widgets`
|
15
|
+
`api.links.widgets.embedded.widgets.first` | `api.widgets.first`
|
16
|
+
`api.links.widgets.embedded.comments` | `api.widgets.comments`
|
17
|
+
`api.links.widget.expand(id: 3)` | `api.widget(id: 3)`
|
18
|
+
`api.links.widget.expand(id: 3).resource.id` | `api.widget(id: 3).id`
|
19
|
+
|
20
|
+
If you prefer to specify the complete HAL navigational structure, you must rename the methods to their new underscore equivalents. See below.
|
21
|
+
|
22
|
+
#### Change Naviational Elements and HTTP Verbs to Underscore Versions
|
23
|
+
|
24
|
+
Navigational methods and HTTP verbs have been renamed to their underscore versions and are otherwise treated as attributes.
|
25
|
+
|
26
|
+
Instead Of | Write This
|
27
|
+
------------------------------------------------------- | ----------------------------------------------------------------
|
28
|
+
`api.links` | `api._links`
|
29
|
+
`api.links.widgets.embedded.widgets.first` | `api._links.widgets._embedded.first`
|
30
|
+
`api.links.widget.expand(id: 3).resource` | `api._links.widget._expand(id: 3)._resource`
|
31
|
+
`api.get` | `api._get`
|
32
|
+
`api.links.widgets.widget(id: 3).delete` | `api._links.widget._expand(id: 3)._delete`
|
33
|
+
`api.links.widgets.post(name: 'a widget')` | `api._links.widgets._post(name: 'a widget')
|
34
|
+
`api.links.widget.expand(id: 3).put(name: 'updated`) | `api._links.widget._expand(id: 3)._put(name: 'updated')`
|
35
|
+
|
36
|
+
For more information see [#63](https://github.com/codegram/hyperclient/pull/63).
|
37
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'hyperclient'
|
2
|
+
|
3
|
+
api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api')
|
4
|
+
|
5
|
+
api.splines.each do |spline|
|
6
|
+
puts "#{spline.uuid}"
|
7
|
+
puts " reticulated: #{spline.reticulated ? 'yes' : 'no'}"
|
8
|
+
puts " thumbnail: #{spline['images:thumbnail']}"
|
9
|
+
end
|
10
|
+
|
11
|
+
api._links.splines._embedded.splines.each do |_spline|
|
12
|
+
# ... equivalent to the above
|
13
|
+
end
|
14
|
+
|
15
|
+
puts '*' * 10
|
16
|
+
|
17
|
+
spline = api.spline(uuid: 'random-uuid')
|
18
|
+
puts "Spline #{spline.uuid} is #{spline.reticulated ? 'reticulated' : 'not reticulated'}."
|
19
|
+
|
20
|
+
# puts api._links.spline._expand(uuid: 'uuid')._resource._attributes.reticulated
|
21
|
+
|
22
|
+
# spline.to_h
|
@@ -2,15 +2,15 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
|
|
2
2
|
include API
|
3
3
|
|
4
4
|
step 'I should be able to navigate to posts and authors' do
|
5
|
-
api.
|
6
|
-
api.
|
5
|
+
api._links.posts._resource
|
6
|
+
api._links['api:authors']._resource
|
7
7
|
|
8
8
|
assert_requested :get, 'http://api.example.org/posts'
|
9
9
|
assert_requested :get, 'http://api.example.org/authors'
|
10
10
|
end
|
11
11
|
|
12
12
|
step 'I search for a post with a templated link' do
|
13
|
-
api.
|
13
|
+
api._links.search._expand(q: 'something')._resource
|
14
14
|
end
|
15
15
|
|
16
16
|
step 'the API should receive the request with all the params' do
|
@@ -18,16 +18,16 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
|
|
18
18
|
end
|
19
19
|
|
20
20
|
step 'I load a single post' do
|
21
|
-
@post = api.
|
21
|
+
@post = api._links.posts._links.last_post
|
22
22
|
end
|
23
23
|
|
24
24
|
step 'I should be able to access it\'s title and body' do
|
25
|
-
@post.
|
26
|
-
@post.
|
25
|
+
@post._attributes.title.wont_equal nil
|
26
|
+
@post._attributes.body.wont_equal nil
|
27
27
|
end
|
28
28
|
|
29
29
|
step 'I should also be able to access it\'s embedded comments' do
|
30
|
-
comment = @post.
|
31
|
-
comment.
|
30
|
+
comment = @post._embedded.comments.first
|
31
|
+
comment._attributes.title.wont_equal nil
|
32
32
|
end
|
33
33
|
end
|
@@ -6,12 +6,12 @@ class Spinach::Features::DefaultConfig < Spinach::FeatureSteps
|
|
6
6
|
end
|
7
7
|
|
8
8
|
step 'the request should have been sent with the correct JSON headers' do
|
9
|
-
assert_requested :get, 'api.example.org', headers: {'Content-Type' => 'application/json', 'Accept' => 'application/json'}
|
9
|
+
assert_requested :get, 'api.example.org', headers: { 'Content-Type' => 'application/json', 'Accept' => 'application/json' }
|
10
10
|
end
|
11
11
|
|
12
12
|
step 'I send some data to the API' do
|
13
|
-
stub_request(:post,
|
14
|
-
api.
|
13
|
+
stub_request(:post, 'http://api.example.org/posts')
|
14
|
+
assert_equal 200, api._links.posts._post(title: 'My first blog post').status
|
15
15
|
end
|
16
16
|
|
17
17
|
step 'it should have been encoded as JSON' do
|
@@ -19,11 +19,11 @@ class Spinach::Features::DefaultConfig < Spinach::FeatureSteps
|
|
19
19
|
end
|
20
20
|
|
21
21
|
step 'I get some data from the API' do
|
22
|
-
@posts = api.
|
22
|
+
@posts = api._links.posts
|
23
23
|
end
|
24
24
|
|
25
25
|
step 'it should have been parsed as JSON' do
|
26
|
-
@posts.
|
27
|
-
@posts.
|
26
|
+
@posts._attributes.total_posts.to_i.must_equal 9
|
27
|
+
@posts._attributes['total_posts'].to_i.must_equal 9
|
28
28
|
end
|
29
29
|
end
|
data/features/support/api.rb
CHANGED
@@ -5,9 +5,9 @@ module API
|
|
5
5
|
include Spinach::Fixtures
|
6
6
|
|
7
7
|
before do
|
8
|
-
stub_request(:any, %r{api.example.org*}).to_return(body: root_response, headers:{'Content-Type' => 'application/json'})
|
9
|
-
stub_request(:get, 'api.example.org/posts').to_return(body: posts_response, headers: {'Content-Type' => 'application/json'})
|
10
|
-
stub_request(:get, 'api.example.org/posts/1').to_return(body: post_response, headers: {'Content-Type' => 'application/json'})
|
8
|
+
stub_request(:any, %r{api.example.org*}).to_return(body: root_response, headers: { 'Content-Type' => 'application/json' })
|
9
|
+
stub_request(:get, 'api.example.org/posts').to_return(body: posts_response, headers: { 'Content-Type' => 'application/json' })
|
10
|
+
stub_request(:get, 'api.example.org/posts/1').to_return(body: post_response, headers: { 'Content-Type' => 'application/json' })
|
11
11
|
end
|
12
12
|
|
13
13
|
def api
|
@@ -15,7 +15,7 @@ module API
|
|
15
15
|
end
|
16
16
|
|
17
17
|
step 'I connect to the API' do
|
18
|
-
api.
|
18
|
+
api._links
|
19
19
|
end
|
20
20
|
|
21
21
|
after do
|
data/hyperclient.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
require File.expand_path('../lib/hyperclient/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = [
|
6
|
-
gem.email = [
|
7
|
-
gem.description =
|
8
|
-
gem.summary =
|
9
|
-
gem.homepage =
|
10
|
-
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
5
|
+
gem.authors = ['Oriol Gual']
|
6
|
+
gem.email = ['oriol.gual@gmail.com']
|
7
|
+
gem.description = 'HyperClient is a Ruby Hypermedia API client.'
|
8
|
+
gem.summary = ''
|
9
|
+
gem.homepage = 'http://codegram.github.com/hyperclient/'
|
10
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
11
11
|
gem.files = `git ls-files`.split("\n")
|
12
12
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
-
gem.name =
|
14
|
-
gem.require_paths = [
|
13
|
+
gem.name = 'hyperclient'
|
14
|
+
gem.require_paths = ['lib']
|
15
15
|
gem.version = Hyperclient::VERSION
|
16
16
|
|
17
17
|
gem.add_dependency 'faraday', '~> 0.8'
|
@@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.add_dependency 'faraday_middleware', '~> 0.9'
|
20
20
|
gem.add_dependency 'uri_template', '~> 0.5'
|
21
21
|
gem.add_dependency 'net-http-digest_auth', '~> 1.2'
|
22
|
+
gem.add_dependency 'faraday-digestauth', '~> 0.2'
|
22
23
|
|
23
24
|
gem.add_development_dependency 'minitest', '~> 3.4.0'
|
24
25
|
gem.add_development_dependency 'turn', '~> 0.9'
|
data/lib/faraday/connection.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'faraday'
|
2
|
-
|
2
|
+
require 'faraday/digestauth'
|
3
3
|
|
4
4
|
module Faraday
|
5
5
|
# Reopen Faraday::Connection to add a helper to set the digest auth data.
|
@@ -11,7 +11,7 @@ module Faraday
|
|
11
11
|
# password - A String with the password.
|
12
12
|
#
|
13
13
|
def digest_auth(user, password)
|
14
|
-
|
14
|
+
builder.insert(0, Faraday::Request::DigestAuth, user, password)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/hyperclient.rb
CHANGED
@@ -17,7 +17,7 @@ module Hyperclient
|
|
17
17
|
#
|
18
18
|
def initialize(representation)
|
19
19
|
@collection = if representation.is_a?(Hash)
|
20
|
-
representation.delete_if {|key,
|
20
|
+
representation.delete_if { |key, _value| RESERVED_PROPERTIES.any? { |p| p.match(key) } }
|
21
21
|
else
|
22
22
|
representation
|
23
23
|
end
|
@@ -69,15 +69,15 @@ module Hyperclient
|
|
69
69
|
# `collection['name']`
|
70
70
|
#
|
71
71
|
# Returns an Object.
|
72
|
-
def method_missing(method_name, *
|
72
|
+
def method_missing(method_name, *_args, &_block)
|
73
73
|
@collection.fetch(method_name.to_s) do
|
74
|
-
|
74
|
+
fail "Could not find `#{method_name}` in #{self.class.name}"
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
78
|
# Internal: Accessory method to allow the collection respond to the
|
79
79
|
# methods that will hit method_missing.
|
80
|
-
def respond_to_missing?(method_name,
|
80
|
+
def respond_to_missing?(method_name, _include_private = false)
|
81
81
|
@collection.include?(method_name.to_s)
|
82
82
|
end
|
83
83
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'hyperclient/resource'
|
2
|
+
|
3
|
+
module Hyperclient
|
4
|
+
# Internal: Curies are named tokens that you can define in the document and use
|
5
|
+
# to express curie relation URIs in a friendlier, more compact fashion.
|
6
|
+
#
|
7
|
+
class Curie
|
8
|
+
# Public: Initializes a new Curie.
|
9
|
+
#
|
10
|
+
# curie - The String with the URI of the curie.
|
11
|
+
# entry_point - The EntryPoint object to inject the cofnigutation.
|
12
|
+
def initialize(curie_hash, entry_point)
|
13
|
+
@curie_hash = curie_hash
|
14
|
+
@entry_point = entry_point
|
15
|
+
end
|
16
|
+
|
17
|
+
# Public: Indicates if the curie is an URITemplate or a regular URI.
|
18
|
+
#
|
19
|
+
# Returns true if it is templated.
|
20
|
+
# Returns false if it not templated.
|
21
|
+
def templated?
|
22
|
+
!!@curie_hash['templated']
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: Returns the name property of the Curie
|
26
|
+
def name
|
27
|
+
@curie_hash['name']
|
28
|
+
end
|
29
|
+
|
30
|
+
# Public: Returns the href property of the Curie
|
31
|
+
def href
|
32
|
+
@curie_hash['href']
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
"#<#{self.class.name} #{@curie_hash}>"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Public: Expands the Curie when is templated with the given variables.
|
40
|
+
#
|
41
|
+
# rel - The rel to expand.
|
42
|
+
#
|
43
|
+
# Returns a new expanded url.
|
44
|
+
def expand(rel)
|
45
|
+
return rel unless rel && templated?
|
46
|
+
href.gsub('{rel}', rel) if href
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -19,7 +19,7 @@ module Hyperclient
|
|
19
19
|
#
|
20
20
|
# url - A String with the entry point of your API.
|
21
21
|
def initialize(url)
|
22
|
-
@link = {'href' => url}
|
22
|
+
@link = { 'href' => url }
|
23
23
|
@entry_point = self
|
24
24
|
end
|
25
25
|
|
@@ -27,10 +27,11 @@ module Hyperclient
|
|
27
27
|
#
|
28
28
|
# Returns a Faraday::Connection.
|
29
29
|
def connection
|
30
|
-
@connection ||= Faraday.new(
|
30
|
+
@connection ||= Faraday.new(_url, { headers: default_headers }, &default_faraday_block)
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
34
|
+
|
34
35
|
# Internal: Returns a block to initialize the Faraday connection. The
|
35
36
|
# default block includes a middleware to encode requests as JSON, a
|
36
37
|
# response middleware to parse JSON responses and sets the adapter as
|
@@ -42,7 +43,8 @@ module Hyperclient
|
|
42
43
|
# Returns a block.
|
43
44
|
def default_faraday_block
|
44
45
|
lambda do |faraday|
|
45
|
-
faraday.
|
46
|
+
faraday.use FaradayMiddleware::FollowRedirects
|
47
|
+
faraday.request :json
|
46
48
|
faraday.response :json, content_type: /\bjson$/
|
47
49
|
faraday.adapter :net_http
|
48
50
|
end
|
@@ -53,7 +55,7 @@ module Hyperclient
|
|
53
55
|
#
|
54
56
|
# Returns a Hash.
|
55
57
|
def default_headers
|
56
|
-
{'Content-Type' => 'application/json', 'Accept' => 'application/json'}
|
58
|
+
{ 'Content-Type' => 'application/json', 'Accept' => 'application/json' }
|
57
59
|
end
|
58
60
|
end
|
59
61
|
end
|
data/lib/hyperclient/link.rb
CHANGED
@@ -3,16 +3,18 @@ require 'uri_template'
|
|
3
3
|
require 'futuroscope'
|
4
4
|
|
5
5
|
module Hyperclient
|
6
|
-
# Internal: The Link is
|
6
|
+
# Internal: The Link is used to let a Resource interact with the API.
|
7
7
|
#
|
8
8
|
class Link
|
9
9
|
# Public: Initializes a new Link.
|
10
10
|
#
|
11
|
+
# key - The key or name of the link.
|
11
12
|
# link - The String with the URI of the link.
|
12
13
|
# entry_point - The EntryPoint object to inject the cofnigutation.
|
13
14
|
# uri_variables - The optional Hash with the variables to expand the link
|
14
15
|
# if it is templated.
|
15
|
-
def initialize(link, entry_point, uri_variables = nil)
|
16
|
+
def initialize(key, link, entry_point, uri_variables = nil)
|
17
|
+
@key = key
|
16
18
|
@link = link
|
17
19
|
@entry_point = entry_point
|
18
20
|
@uri_variables = uri_variables
|
@@ -22,7 +24,7 @@ module Hyperclient
|
|
22
24
|
#
|
23
25
|
# Returns true if it is templated.
|
24
26
|
# Returns false if it not templated.
|
25
|
-
def
|
27
|
+
def _templated?
|
26
28
|
!!@link['templated']
|
27
29
|
end
|
28
30
|
|
@@ -31,62 +33,62 @@ module Hyperclient
|
|
31
33
|
# uri_variables - The Hash with the variables to expand the URITemplate.
|
32
34
|
#
|
33
35
|
# Returns a new Link with the expanded variables.
|
34
|
-
def
|
35
|
-
self.class.new(@link, @entry_point, uri_variables)
|
36
|
+
def _expand(uri_variables)
|
37
|
+
self.class.new(@key, @link, @entry_point, uri_variables)
|
36
38
|
end
|
37
39
|
|
38
40
|
# Public: Returns the url of the Link.
|
39
41
|
#
|
40
42
|
# Raises MissingURITemplateVariables if the Link is templated but there are
|
41
43
|
# no uri variables to expand it.
|
42
|
-
def
|
43
|
-
return @link['href'] unless
|
44
|
-
|
44
|
+
def _url
|
45
|
+
return @link['href'] unless _templated?
|
46
|
+
fail MissingURITemplateVariablesException if @uri_variables.nil?
|
45
47
|
|
46
|
-
@url ||=
|
48
|
+
@url ||= _uri_template.expand(@uri_variables)
|
47
49
|
end
|
48
50
|
|
49
51
|
# Public: Returns an array of variables from the URITemplate.
|
50
52
|
#
|
51
53
|
# Returns an empty array for regular URIs.
|
52
|
-
def
|
53
|
-
|
54
|
+
def _variables
|
55
|
+
_uri_template.variables
|
54
56
|
end
|
55
57
|
|
56
58
|
# Public: Returns the type property of the Link
|
57
|
-
def
|
59
|
+
def _type
|
58
60
|
@link['type']
|
59
61
|
end
|
60
62
|
|
61
63
|
# Public: Returns the name property of the Link
|
62
|
-
def
|
64
|
+
def _name
|
63
65
|
@link['name']
|
64
66
|
end
|
65
67
|
|
66
68
|
# Public: Returns the deprecation property of the Link
|
67
|
-
def
|
69
|
+
def _deprecation
|
68
70
|
@link['deprecation']
|
69
71
|
end
|
70
72
|
|
71
73
|
# Public: Returns the profile property of the Link
|
72
|
-
def
|
74
|
+
def _profile
|
73
75
|
@link['profile']
|
74
76
|
end
|
75
77
|
|
76
78
|
# Public: Returns the title property of the Link
|
77
|
-
def
|
79
|
+
def _title
|
78
80
|
@link['title']
|
79
81
|
end
|
80
82
|
|
81
83
|
# Public: Returns the hreflang property of the Link
|
82
|
-
def
|
84
|
+
def _hreflang
|
83
85
|
@link['hreflang']
|
84
86
|
end
|
85
87
|
|
86
88
|
# Public: Returns the Resource which the Link is pointing to.
|
87
|
-
def
|
89
|
+
def _resource
|
88
90
|
@resource ||= begin
|
89
|
-
response =
|
91
|
+
response = _get
|
90
92
|
|
91
93
|
if response.success?
|
92
94
|
Resource.new(response.body, @entry_point, response)
|
@@ -96,64 +98,71 @@ module Hyperclient
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
99
|
-
def
|
101
|
+
def _connection
|
100
102
|
@entry_point.connection
|
101
103
|
end
|
102
104
|
|
103
|
-
def
|
104
|
-
Futuroscope::Future.new
|
105
|
-
|
106
|
-
|
105
|
+
def _get
|
106
|
+
Futuroscope::Future.new do
|
107
|
+
_connection.get(_url)
|
108
|
+
end
|
107
109
|
end
|
108
110
|
|
109
|
-
def
|
110
|
-
Futuroscope::Future.new
|
111
|
-
|
112
|
-
|
111
|
+
def _options
|
112
|
+
Futuroscope::Future.new do
|
113
|
+
_connection.run_request(:options, _url, nil, nil)
|
114
|
+
end
|
113
115
|
end
|
114
116
|
|
115
|
-
def
|
116
|
-
Futuroscope::Future.new
|
117
|
-
|
118
|
-
|
117
|
+
def _head
|
118
|
+
Futuroscope::Future.new do
|
119
|
+
_connection.head(_url)
|
120
|
+
end
|
119
121
|
end
|
120
122
|
|
121
|
-
def
|
122
|
-
Futuroscope::Future.new
|
123
|
-
|
124
|
-
|
123
|
+
def _delete
|
124
|
+
Futuroscope::Future.new do
|
125
|
+
_connection.delete(_url)
|
126
|
+
end
|
125
127
|
end
|
126
128
|
|
127
|
-
def
|
128
|
-
Futuroscope::Future.new
|
129
|
-
|
130
|
-
|
129
|
+
def _post(params = {})
|
130
|
+
Futuroscope::Future.new do
|
131
|
+
_connection.post(_url, params)
|
132
|
+
end
|
131
133
|
end
|
132
134
|
|
133
|
-
def
|
134
|
-
Futuroscope::Future.new
|
135
|
-
|
136
|
-
|
135
|
+
def _put(params = {})
|
136
|
+
Futuroscope::Future.new do
|
137
|
+
_connection.put(_url, params)
|
138
|
+
end
|
137
139
|
end
|
138
140
|
|
139
|
-
def
|
140
|
-
Futuroscope::Future.new
|
141
|
-
|
142
|
-
|
141
|
+
def _patch(params = {})
|
142
|
+
Futuroscope::Future.new do
|
143
|
+
_connection.patch(_url, params)
|
144
|
+
end
|
143
145
|
end
|
144
146
|
|
145
147
|
def inspect
|
146
|
-
"#<#{self.class.name} #{@link}>"
|
148
|
+
"#<#{self.class.name}(#{@key}) #{@link}>"
|
149
|
+
end
|
150
|
+
|
151
|
+
def to_s
|
152
|
+
_url
|
147
153
|
end
|
148
154
|
|
149
155
|
private
|
156
|
+
|
150
157
|
# Internal: Delegate the method to the API if it exists.
|
151
158
|
#
|
152
|
-
# This allows `api.links.posts.embedded`
|
153
|
-
# `api.links.posts.resource.embedded`
|
159
|
+
# This allows `api.posts` instead of `api.links.posts.embedded`
|
154
160
|
def method_missing(method, *args, &block)
|
155
|
-
if
|
156
|
-
|
161
|
+
if @key && _resource.respond_to?(@key) && (delegate = _resource.send(@key)) && delegate.respond_to?(method.to_s)
|
162
|
+
# named.named becomes named
|
163
|
+
delegate.send(method, *args, &block)
|
164
|
+
elsif _resource.respond_to?(method.to_s)
|
165
|
+
_resource.send(method, *args, &block)
|
157
166
|
else
|
158
167
|
super
|
159
168
|
end
|
@@ -161,8 +170,12 @@ module Hyperclient
|
|
161
170
|
|
162
171
|
# Internal: Accessory method to allow the link respond to the
|
163
172
|
# methods that will hit method_missing.
|
164
|
-
def respond_to_missing?(method,
|
165
|
-
|
173
|
+
def respond_to_missing?(method, _include_private = false)
|
174
|
+
if @key && _resource.respond_to?(@key) && (delegate = _resource.send(@key)) && delegate.respond_to?(method.to_s)
|
175
|
+
true
|
176
|
+
else
|
177
|
+
_resource.respond_to?(method.to_s)
|
178
|
+
end
|
166
179
|
end
|
167
180
|
|
168
181
|
# Internal: avoid delegating to resource
|
@@ -174,7 +187,7 @@ module Hyperclient
|
|
174
187
|
end
|
175
188
|
|
176
189
|
# Internal: Memoization for a URITemplate instance
|
177
|
-
def
|
190
|
+
def _uri_template
|
178
191
|
@uri_template ||= URITemplate.new(@link['href'])
|
179
192
|
end
|
180
193
|
end
|
@@ -182,10 +195,9 @@ module Hyperclient
|
|
182
195
|
# Public: Exception that is raised when building a templated Link without uri
|
183
196
|
# variables.
|
184
197
|
class MissingURITemplateVariablesException < StandardError
|
185
|
-
|
186
198
|
# Public: Returns a String with the exception message.
|
187
199
|
def message
|
188
|
-
|
200
|
+
'The URL to this links is templated, but no variables where given.'
|
189
201
|
end
|
190
202
|
end
|
191
203
|
end
|