hyperclient 0.8.5 → 1.0.1
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 +5 -5
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +14 -42
- data/.travis.yml +10 -13
- data/CHANGELOG.md +61 -18
- data/Dangerfile +2 -2
- data/Gemfile +10 -7
- data/LICENSE +1 -1
- data/README.md +47 -36
- data/Rakefile +2 -8
- data/UPGRADING.md +16 -0
- data/features/api_navigation.feature +5 -0
- data/features/steps/api_navigation.rb +17 -4
- data/features/steps/default_config.rb +3 -3
- data/features/support/api.rb +8 -2
- data/features/support/fixtures.rb +96 -2
- data/hyperclient.gemspec +4 -8
- data/lib/hyperclient/collection.rb +1 -1
- data/lib/hyperclient/curie.rb +2 -1
- data/lib/hyperclient/entry_point.rb +15 -9
- data/lib/hyperclient/link.rb +31 -15
- data/lib/hyperclient/link_collection.rb +3 -1
- data/lib/hyperclient/resource.rb +35 -6
- data/lib/hyperclient/resource_collection.rb +3 -1
- data/lib/hyperclient/version.rb +1 -1
- data/test/fixtures/element.json +15 -15
- data/test/hyperclient/attributes_test.rb +9 -9
- data/test/hyperclient/collection_test.rb +15 -15
- data/test/hyperclient/curie_test.rb +4 -4
- data/test/hyperclient/entry_point_test.rb +44 -53
- data/test/hyperclient/link_collection_test.rb +15 -15
- data/test/hyperclient/link_test.rb +53 -239
- data/test/hyperclient/resource_collection_test.rb +6 -6
- data/test/hyperclient/resource_test.rb +40 -24
- data/test/hyperclient_test.rb +9 -10
- data/test/test_helper.rb +8 -9
- metadata +33 -58
- data/lib/faraday/connection.rb +0 -17
- data/test/faraday/connection_test.rb +0 -29
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
+
|
2
3
|
require 'rubygems'
|
3
4
|
require 'bundler'
|
4
5
|
Bundler.setup :default, :test, :development
|
@@ -13,13 +14,6 @@ if ENV['COVERAGE']
|
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
require 'yard'
|
17
|
-
YARD::Config.load_plugin('yard-tomdoc')
|
18
|
-
YARD::Rake::YardocTask.new do |t|
|
19
|
-
t.files = ['lib/**/*.rb']
|
20
|
-
t.options = %w(-r README.md)
|
21
|
-
end
|
22
|
-
|
23
17
|
require 'rake/testtask'
|
24
18
|
|
25
19
|
Rake::TestTask.new(:test) do |t|
|
@@ -38,4 +32,4 @@ end
|
|
38
32
|
require 'rubocop/rake_task'
|
39
33
|
RuboCop::RakeTask.new(:rubocop)
|
40
34
|
|
41
|
-
task default: [
|
35
|
+
task default: %i[test spinach rubocop]
|
data/UPGRADING.md
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
Upgrading Hyperclient
|
2
2
|
=====================
|
3
3
|
|
4
|
+
### Upgrading to >= 0.9.0
|
5
|
+
|
6
|
+
Previous versions of Hyperclient performed asynchronous requests using [futuroscope](https://github.com/codegram/futuroscope) by default, which could be disabled by providing the `:async` option to each Hyperclient instance. This has been removed and you can remove any such code.
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
api = Hyperclient.new('https://grape-with-roar.herokuapp.com/api') do |client|
|
10
|
+
client.options[:async] = false
|
11
|
+
end
|
12
|
+
```
|
13
|
+
|
14
|
+
The default new behavior is synchronous. We recommend [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) for your asynchronous needs.
|
15
|
+
|
16
|
+
Include [futuroscope](https://github.com/codegram/futuroscope) in your `Gemfile` and wrap Hyperclient requests into `Futuroscope::Future.new` blocks to get the old behavior.
|
17
|
+
|
18
|
+
See [#133](https://github.com/codegram/hyperclient/pull/133) and [#123](https://github.com/codegram/hyperclient/issues/123) for more information.
|
19
|
+
|
4
20
|
### Upgrading to >= 0.8.0
|
5
21
|
|
6
22
|
### Changes in curies
|
@@ -7,6 +7,11 @@ Feature: API navigation
|
|
7
7
|
When I connect to the API
|
8
8
|
Then I should be able to navigate to posts and authors
|
9
9
|
|
10
|
+
Scenario: Links
|
11
|
+
When I connect to the API
|
12
|
+
Then I should be able to paginate posts
|
13
|
+
Then I should be able to paginate authors
|
14
|
+
|
10
15
|
Scenario: Templated links
|
11
16
|
Given I connect to the API
|
12
17
|
When I search for a post with a templated link
|
@@ -9,6 +9,19 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
|
|
9
9
|
assert_requested :get, 'http://api.example.org/authors'
|
10
10
|
end
|
11
11
|
|
12
|
+
step 'I should be able to paginate posts' do
|
13
|
+
assert_kind_of Enumerator, api.posts.each
|
14
|
+
assert_equal 4, api.posts.to_a.count
|
15
|
+
assert_requested :get, 'http://api.example.org/posts'
|
16
|
+
assert_requested :get, 'http://api.example.org/posts?page=2'
|
17
|
+
assert_requested :get, 'http://api.example.org/posts?page=3'
|
18
|
+
end
|
19
|
+
|
20
|
+
step 'I should be able to paginate authors' do
|
21
|
+
assert_equal 1, api._links['api:authors'].to_a.count
|
22
|
+
assert_requested :get, 'http://api.example.org/authors'
|
23
|
+
end
|
24
|
+
|
12
25
|
step 'I search for a post with a templated link' do
|
13
26
|
api._links.search._expand(q: 'something')._resource
|
14
27
|
end
|
@@ -18,7 +31,7 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
|
|
18
31
|
end
|
19
32
|
|
20
33
|
step 'I search for posts by tag with a templated link' do
|
21
|
-
api._links.tagged._expand(tags: %w
|
34
|
+
api._links.tagged._expand(tags: %w[foo bar])._resource
|
22
35
|
end
|
23
36
|
|
24
37
|
step 'the API should receive the request for posts by tag with all the params' do
|
@@ -50,8 +63,8 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
|
|
50
63
|
step 'I should be able to count embedded items' do
|
51
64
|
assert_equal 2, api._links.posts._resource._embedded.posts.count
|
52
65
|
assert_equal 2, api.posts._embedded.posts.count
|
53
|
-
assert_equal
|
54
|
-
assert_equal
|
66
|
+
assert_equal 4, api.posts.count
|
67
|
+
assert_equal 4, api.posts.map.count
|
55
68
|
end
|
56
69
|
|
57
70
|
step 'I should be able to iterate over embedded items' do
|
@@ -59,6 +72,6 @@ class Spinach::Features::ApiNavigation < Spinach::FeatureSteps
|
|
59
72
|
api.posts.each do |_post|
|
60
73
|
count += 1
|
61
74
|
end
|
62
|
-
assert_equal
|
75
|
+
assert_equal 4, count
|
63
76
|
end
|
64
77
|
end
|
@@ -12,7 +12,7 @@ class Spinach::Features::DefaultConfig < Spinach::FeatureSteps
|
|
12
12
|
end
|
13
13
|
|
14
14
|
step 'I send some data to the API' do
|
15
|
-
stub_request(:post, 'http://api.example.org/posts')
|
15
|
+
stub_request(:post, 'http://api.example.org/posts').to_return(headers: { 'Content-Type' => 'application/hal+json' })
|
16
16
|
assert_equal 200, api._links.posts._post(title: 'My first blog post')._response.status
|
17
17
|
end
|
18
18
|
|
@@ -25,7 +25,7 @@ class Spinach::Features::DefaultConfig < Spinach::FeatureSteps
|
|
25
25
|
end
|
26
26
|
|
27
27
|
step 'it should have been parsed as JSON' do
|
28
|
-
@posts._attributes.total_posts.to_i.must_equal
|
29
|
-
@posts._attributes['total_posts'].to_i.must_equal
|
28
|
+
@posts._attributes.total_posts.to_i.must_equal 4
|
29
|
+
@posts._attributes['total_posts'].to_i.must_equal 4
|
30
30
|
end
|
31
31
|
end
|
data/features/support/api.rb
CHANGED
@@ -7,9 +7,15 @@ module API
|
|
7
7
|
before do
|
8
8
|
WebMock::Config.instance.query_values_notation = :flat_array
|
9
9
|
|
10
|
-
stub_request(:any,
|
10
|
+
stub_request(:any, /api.example.org*/).to_return(body: root_response, headers: { 'Content-Type' => 'application/hal+json' })
|
11
|
+
stub_request(:get, 'api.example.org').to_return(body: root_response, headers: { 'Content-Type' => 'application/hal+json' })
|
12
|
+
stub_request(:get, 'api.example.org/authors').to_return(body: authors_response, headers: { 'Content-Type' => 'application/hal+json' })
|
11
13
|
stub_request(:get, 'api.example.org/posts').to_return(body: posts_response, headers: { 'Content-Type' => 'application/hal+json' })
|
12
|
-
stub_request(:get, 'api.example.org/posts
|
14
|
+
stub_request(:get, 'api.example.org/posts?page=2').to_return(body: posts_page2_response, headers: { 'Content-Type' => 'application/hal+json' })
|
15
|
+
stub_request(:get, 'api.example.org/posts?page=3').to_return(body: posts_page3_response, headers: { 'Content-Type' => 'application/hal+json' })
|
16
|
+
stub_request(:get, 'api.example.org/posts/1').to_return(body: post1_response, headers: { 'Content-Type' => 'application/hal+json' })
|
17
|
+
stub_request(:get, 'api.example.org/posts/2').to_return(body: post2_response, headers: { 'Content-Type' => 'application/hal+json' })
|
18
|
+
stub_request(:get, 'api.example.org/posts/3').to_return(body: post3_response, headers: { 'Content-Type' => 'application/hal+json' })
|
13
19
|
stub_request(:get, 'api.example.org/page2').to_return(body: page2_response, headers: { 'Content-Type' => 'application/hal+json' })
|
14
20
|
stub_request(:get, 'api.example.org/page3').to_return(body: page3_response, headers: { 'Content-Type' => 'application/hal+json' })
|
15
21
|
end
|
@@ -15,13 +15,32 @@ module Spinach
|
|
15
15
|
}'
|
16
16
|
end
|
17
17
|
|
18
|
+
def authors_response
|
19
|
+
'{
|
20
|
+
"_links": {
|
21
|
+
"self": { "href": "/authors" }
|
22
|
+
},
|
23
|
+
"_embedded": {
|
24
|
+
"api:authors": [
|
25
|
+
{
|
26
|
+
"name": "Lorem Ipsum",
|
27
|
+
"_links": {
|
28
|
+
"self": { "href": "/authors/1" }
|
29
|
+
}
|
30
|
+
}
|
31
|
+
]
|
32
|
+
}
|
33
|
+
}'
|
34
|
+
end
|
35
|
+
|
18
36
|
def posts_response
|
19
37
|
'{
|
20
38
|
"_links": {
|
21
39
|
"self": { "href": "/posts" },
|
40
|
+
"next": {"href": "/posts?page=2"},
|
22
41
|
"last_post": {"href": "/posts/1"}
|
23
42
|
},
|
24
|
-
"total_posts": "
|
43
|
+
"total_posts": "4",
|
25
44
|
"_embedded": {
|
26
45
|
"posts": [
|
27
46
|
{
|
@@ -43,7 +62,48 @@ module Spinach
|
|
43
62
|
}'
|
44
63
|
end
|
45
64
|
|
46
|
-
def
|
65
|
+
def posts_page2_response
|
66
|
+
'{
|
67
|
+
"_links": {
|
68
|
+
"self": { "href": "/posts?page=2" },
|
69
|
+
"next": { "href": "/posts?page=3" }
|
70
|
+
},
|
71
|
+
"total_posts": "4",
|
72
|
+
"_embedded": {
|
73
|
+
"posts": [
|
74
|
+
{
|
75
|
+
"title": "My third blog post",
|
76
|
+
"body": "Lorem ipsum dolor sit amet",
|
77
|
+
"_links": {
|
78
|
+
"self": { "href": "/posts/3" }
|
79
|
+
}
|
80
|
+
}
|
81
|
+
]
|
82
|
+
}
|
83
|
+
}'
|
84
|
+
end
|
85
|
+
|
86
|
+
def posts_page3_response
|
87
|
+
'{
|
88
|
+
"_links": {
|
89
|
+
"self": { "href": "/posts?page=3" }
|
90
|
+
},
|
91
|
+
"total_posts": "4",
|
92
|
+
"_embedded": {
|
93
|
+
"posts": [
|
94
|
+
{
|
95
|
+
"title": "My third blog post",
|
96
|
+
"body": "Lorem ipsum dolor sit amet",
|
97
|
+
"_links": {
|
98
|
+
"self": { "href": "/posts/4" }
|
99
|
+
}
|
100
|
+
}
|
101
|
+
]
|
102
|
+
}
|
103
|
+
}'
|
104
|
+
end
|
105
|
+
|
106
|
+
def post1_response
|
47
107
|
'{
|
48
108
|
"_links": {
|
49
109
|
"self": { "href": "/posts/1" }
|
@@ -60,6 +120,40 @@ module Spinach
|
|
60
120
|
}'
|
61
121
|
end
|
62
122
|
|
123
|
+
def post2_response
|
124
|
+
'{
|
125
|
+
"_links": {
|
126
|
+
"self": { "href": "/posts/2" }
|
127
|
+
},
|
128
|
+
"title": "My first blog post",
|
129
|
+
"body": "Lorem ipsum dolor sit amet",
|
130
|
+
"_embedded": {
|
131
|
+
"comments": [
|
132
|
+
{
|
133
|
+
"title": "Some comment"
|
134
|
+
}
|
135
|
+
]
|
136
|
+
}
|
137
|
+
}'
|
138
|
+
end
|
139
|
+
|
140
|
+
def post3_response
|
141
|
+
'{
|
142
|
+
"_links": {
|
143
|
+
"self": { "href": "/posts/3" }
|
144
|
+
},
|
145
|
+
"title": "My first blog post",
|
146
|
+
"body": "Lorem ipsum dolor sit amet",
|
147
|
+
"_embedded": {
|
148
|
+
"comments": [
|
149
|
+
{
|
150
|
+
"title": "Some comment"
|
151
|
+
}
|
152
|
+
]
|
153
|
+
}
|
154
|
+
}'
|
155
|
+
end
|
156
|
+
|
63
157
|
def page2_response
|
64
158
|
'{
|
65
159
|
"_links": {
|
data/hyperclient.gemspec
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
|
2
|
-
require File.expand_path('../lib/hyperclient/version', __FILE__)
|
1
|
+
require File.expand_path('lib/hyperclient/version', __dir__)
|
3
2
|
|
4
3
|
Gem::Specification.new do |gem|
|
5
4
|
gem.authors = ['Oriol Gual']
|
6
5
|
gem.email = ['oriol.gual@gmail.com']
|
7
|
-
gem.description = '
|
6
|
+
gem.description = 'Hyperclient is a Ruby Hypermedia API client.'
|
8
7
|
gem.summary = ''
|
9
8
|
gem.homepage = 'https://github.com/codegram/hyperclient/'
|
10
9
|
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
@@ -14,11 +13,8 @@ Gem::Specification.new do |gem|
|
|
14
13
|
gem.require_paths = ['lib']
|
15
14
|
gem.version = Hyperclient::VERSION
|
16
15
|
|
16
|
+
gem.add_dependency 'addressable'
|
17
17
|
gem.add_dependency 'faraday', '>= 0.9.0'
|
18
|
-
gem.add_dependency 'futuroscope'
|
19
|
-
gem.add_dependency 'faraday_middleware'
|
20
18
|
gem.add_dependency 'faraday_hal_middleware'
|
21
|
-
gem.add_dependency '
|
22
|
-
gem.add_dependency 'net-http-digest_auth'
|
23
|
-
gem.add_dependency 'faraday-digestauth'
|
19
|
+
gem.add_dependency 'faraday_middleware'
|
24
20
|
end
|
@@ -35,7 +35,7 @@ module Hyperclient
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# Public: Returns a value from the collection for the given key.
|
38
|
-
# If the key can
|
38
|
+
# If the key can't be found, there are several options:
|
39
39
|
# With no other arguments, it will raise an KeyError exception;
|
40
40
|
# if default is given, then that will be returned;
|
41
41
|
#
|
data/lib/hyperclient/curie.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'faraday_middleware'
|
2
2
|
require 'faraday_hal_middleware'
|
3
|
-
require_relative '../faraday/connection'
|
4
3
|
|
5
4
|
module Hyperclient
|
6
5
|
# Public: Exception that is raised when trying to modify an
|
@@ -30,7 +29,7 @@ module Hyperclient
|
|
30
29
|
extend Forwardable
|
31
30
|
|
32
31
|
# Public: Delegates common methods to be used with the Faraday connection.
|
33
|
-
def_delegators :connection, :
|
32
|
+
def_delegators :connection, :params, :params=
|
34
33
|
|
35
34
|
# Public: Initializes an EntryPoint.
|
36
35
|
#
|
@@ -38,9 +37,11 @@ module Hyperclient
|
|
38
37
|
def initialize(url, &_block)
|
39
38
|
@link = { 'href' => url }
|
40
39
|
@entry_point = self
|
41
|
-
@options = {
|
40
|
+
@options = {}
|
42
41
|
@connection = nil
|
43
42
|
@resource = nil
|
43
|
+
@key = nil
|
44
|
+
@uri_variables = nil
|
44
45
|
yield self if block_given?
|
45
46
|
end
|
46
47
|
|
@@ -55,12 +56,12 @@ module Hyperclient
|
|
55
56
|
@faraday_options ||= options.dup
|
56
57
|
if block_given?
|
57
58
|
raise ConnectionAlreadyInitializedError if @connection
|
59
|
+
|
58
60
|
@faraday_block = if @faraday_options.delete(:default) == false
|
59
61
|
block
|
60
62
|
else
|
61
63
|
lambda do |conn|
|
62
|
-
default_faraday_block.call
|
63
|
-
yield conn
|
64
|
+
default_faraday_block.call(conn, &block)
|
64
65
|
end
|
65
66
|
end
|
66
67
|
else
|
@@ -73,6 +74,7 @@ module Hyperclient
|
|
73
74
|
# Returns a Hash.
|
74
75
|
def headers
|
75
76
|
return @connection.headers if @connection
|
77
|
+
|
76
78
|
@headers ||= default_headers
|
77
79
|
end
|
78
80
|
|
@@ -81,6 +83,7 @@ module Hyperclient
|
|
81
83
|
# value - A Hash containing headers to include with every API request.
|
82
84
|
def headers=(value)
|
83
85
|
raise ConnectionAlreadyInitializedError if @connection
|
86
|
+
|
84
87
|
@headers = value
|
85
88
|
end
|
86
89
|
|
@@ -96,6 +99,7 @@ module Hyperclient
|
|
96
99
|
# value - A Hash containing options to pass to Faraday
|
97
100
|
def faraday_options=(value)
|
98
101
|
raise ConnectionAlreadyInitializedError if @connection
|
102
|
+
|
99
103
|
@faraday_options = value
|
100
104
|
end
|
101
105
|
|
@@ -111,14 +115,13 @@ module Hyperclient
|
|
111
115
|
# value - A Proc accepting a Faraday::Connection.
|
112
116
|
def faraday_block=(value)
|
113
117
|
raise ConnectionAlreadyInitializedError if @connection
|
118
|
+
|
114
119
|
@faraday_block = value
|
115
120
|
end
|
116
121
|
|
117
122
|
# Public: Read/Set options.
|
118
123
|
#
|
119
|
-
# value - A Hash containing the client options.
|
120
|
-
# to disable the default behavior of performing requests asynchronously
|
121
|
-
# using futures.
|
124
|
+
# value - A Hash containing the client options.
|
122
125
|
attr_accessor :options
|
123
126
|
|
124
127
|
private
|
@@ -133,11 +136,14 @@ module Hyperclient
|
|
133
136
|
#
|
134
137
|
# Returns a block.
|
135
138
|
def default_faraday_block
|
136
|
-
lambda do |connection|
|
139
|
+
lambda do |connection, &block|
|
137
140
|
connection.use Faraday::Response::RaiseError
|
138
141
|
connection.use FaradayMiddleware::FollowRedirects
|
139
142
|
connection.request :hal_json
|
140
143
|
connection.response :hal_json, content_type: /\bjson$/
|
144
|
+
|
145
|
+
block&.call(connection)
|
146
|
+
|
141
147
|
connection.adapter :net_http
|
142
148
|
connection.options.params_encoder = Faraday::FlatParamsEncoder
|
143
149
|
end
|
data/lib/hyperclient/link.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
require '
|
2
|
-
require 'futuroscope'
|
1
|
+
require 'addressable'
|
3
2
|
|
4
3
|
module Hyperclient
|
5
4
|
# Internal: The Link is used to let a Resource interact with the API.
|
6
5
|
#
|
7
6
|
class Link
|
7
|
+
include Enumerable
|
8
|
+
|
8
9
|
# Public: Initializes a new Link.
|
9
10
|
#
|
10
11
|
# key - The key or name of the link.
|
@@ -20,6 +21,25 @@ module Hyperclient
|
|
20
21
|
@resource = nil
|
21
22
|
end
|
22
23
|
|
24
|
+
# Public: Each implementation to allow the class to use the Enumerable
|
25
|
+
# benefits for paginated, embedded items.
|
26
|
+
#
|
27
|
+
# Returns an Enumerator.
|
28
|
+
def each(&block)
|
29
|
+
if block_given?
|
30
|
+
current = self
|
31
|
+
while current
|
32
|
+
coll = current.respond_to?(@key) ? current.send(@key) : _resource
|
33
|
+
coll.each(&block)
|
34
|
+
break unless current._links[:next]
|
35
|
+
|
36
|
+
current = current._links.next
|
37
|
+
end
|
38
|
+
else
|
39
|
+
to_enum(:each)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
23
43
|
# Public: Indicates if the link is an URITemplate or a regular URI.
|
24
44
|
#
|
25
45
|
# Returns true if it is templated.
|
@@ -40,7 +60,8 @@ module Hyperclient
|
|
40
60
|
# Public: Returns the url of the Link.
|
41
61
|
def _url
|
42
62
|
return @link['href'] unless _templated?
|
43
|
-
|
63
|
+
|
64
|
+
@url ||= _uri_template.expand(@uri_variables || {}).to_s
|
44
65
|
end
|
45
66
|
|
46
67
|
# Public: Returns an array of variables from the URITemplate.
|
@@ -126,7 +147,8 @@ module Hyperclient
|
|
126
147
|
# Internal: Delegate the method further down the API if the resource cannot serve it.
|
127
148
|
def method_missing(method, *args, &block)
|
128
149
|
if _resource.respond_to?(method.to_s)
|
129
|
-
_resource.send(method, *args, &block)
|
150
|
+
result = _resource.send(method, *args, &block)
|
151
|
+
result.nil? ? delegate_method(method, *args, &block) : result
|
130
152
|
else
|
131
153
|
super
|
132
154
|
end
|
@@ -137,8 +159,10 @@ module Hyperclient
|
|
137
159
|
# This allows `api.posts` instead of `api._links.posts.embedded.posts`
|
138
160
|
def delegate_method(method, *args, &block)
|
139
161
|
return unless @key && _resource.respond_to?(@key)
|
162
|
+
|
140
163
|
@delegate ||= _resource.send(@key)
|
141
|
-
return unless @delegate
|
164
|
+
return unless @delegate&.respond_to?(method.to_s)
|
165
|
+
|
142
166
|
@delegate.send(method, *args, &block)
|
143
167
|
end
|
144
168
|
|
@@ -162,20 +186,12 @@ module Hyperclient
|
|
162
186
|
|
163
187
|
# Internal: Memoization for a URITemplate instance
|
164
188
|
def _uri_template
|
165
|
-
@uri_template ||=
|
189
|
+
@uri_template ||= Addressable::Template.new(@link['href'])
|
166
190
|
end
|
167
191
|
|
168
192
|
def http_method(method, body = nil)
|
169
193
|
@resource = begin
|
170
|
-
response =
|
171
|
-
if @entry_point.options[:async]
|
172
|
-
Futuroscope::Future.new do
|
173
|
-
@entry_point.connection.run_request(method, _url, body, nil)
|
174
|
-
end
|
175
|
-
else
|
176
|
-
@entry_point.connection.run_request(method, _url, body, nil)
|
177
|
-
end
|
178
|
-
|
194
|
+
response = @entry_point.connection.run_request(method, _url, body, nil)
|
179
195
|
Resource.new(response.body, @entry_point, response)
|
180
196
|
end
|
181
197
|
end
|