spyke 4.1.1 → 5.0.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/README.md +18 -0
- data/circle.yml +1 -1
- data/lib/spyke/exceptions.rb +1 -0
- data/lib/spyke/http.rb +14 -8
- data/lib/spyke/relation.rb +26 -1
- data/lib/spyke/scoping.rb +1 -1
- data/lib/spyke/version.rb +1 -1
- data/test/fallbacks_test.rb +42 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a430604d1097764cd8add4c5b0f44161e5939d4
|
4
|
+
data.tar.gz: af8c8efb25d69ee8555510408edc393b5f8d1e5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 805690aac305cad08aeb0d8f34a63ca17aab8296080d42c51cb9f23117679592c3e8e1addf867595e2d1f82e19ad7607a06b1e2b6c8adf99b7dd4c2a3625d551
|
7
|
+
data.tar.gz: 8337033aea0abef30be2ce84d83e80c947ee643eb3a0214fb6637f8a1404b36c5f1f67c7d02e06b0429aa027010d737aa8a705f9bf92c6cc87d6a199b886892b
|
data/README.md
CHANGED
@@ -167,6 +167,24 @@ remap it in Faraday to match the above. Doing this will allow you to
|
|
167
167
|
show errors returned from the server in forms and f.ex using
|
168
168
|
`@post.errors.full_messages` just like ActiveRecord.
|
169
169
|
|
170
|
+
### Error handling and fallbacks
|
171
|
+
|
172
|
+
Should the API fail to connect or time out, a `Spyke::ConnectionError` will be raised.
|
173
|
+
If you need to recover gracefully from connection problems, you can
|
174
|
+
either rescue that exception or use the `with_fallback` feature:
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
# API is down
|
178
|
+
Article.all # => Spyke::ConnectionError
|
179
|
+
Article.with_fallback.all # => []
|
180
|
+
|
181
|
+
Article.find(1) # => Spyke::ConnectionError
|
182
|
+
Article.with_fallback.find(1) # => nil
|
183
|
+
|
184
|
+
article = Article.with_fallback(Article.new(title: "Dummy")).find(1)
|
185
|
+
article.title # => "Dummy"
|
186
|
+
```
|
187
|
+
|
170
188
|
### Attributes-wrapping
|
171
189
|
|
172
190
|
Spyke, like Rails, by default wraps sent attributes in a root element,
|
data/circle.yml
CHANGED
data/lib/spyke/exceptions.rb
CHANGED
data/lib/spyke/http.rb
CHANGED
@@ -22,14 +22,7 @@ module Spyke
|
|
22
22
|
|
23
23
|
def request(method, path, params = {})
|
24
24
|
ActiveSupport::Notifications.instrument('request.spyke', method: method) do |payload|
|
25
|
-
response =
|
26
|
-
if method == :get
|
27
|
-
request.url path.to_s, params
|
28
|
-
else
|
29
|
-
request.url path.to_s
|
30
|
-
request.body = params
|
31
|
-
end
|
32
|
-
end
|
25
|
+
response = send_request(method, path, params)
|
33
26
|
payload[:url], payload[:status] = response.env.url, response.status
|
34
27
|
Result.new_from_response(response)
|
35
28
|
end
|
@@ -49,6 +42,19 @@ module Spyke
|
|
49
42
|
|
50
43
|
private
|
51
44
|
|
45
|
+
def send_request(method, path, params)
|
46
|
+
connection.send(method) do |request|
|
47
|
+
if method == :get
|
48
|
+
request.url path.to_s, params
|
49
|
+
else
|
50
|
+
request.url path.to_s
|
51
|
+
request.body = params
|
52
|
+
end
|
53
|
+
end
|
54
|
+
rescue Faraday::ConnectionFailed, Faraday::TimeoutError
|
55
|
+
raise ConnectionError
|
56
|
+
end
|
57
|
+
|
52
58
|
def scoped_request(method)
|
53
59
|
uri = new.uri
|
54
60
|
params = current_scope.params.except(*uri.variables)
|
data/lib/spyke/relation.rb
CHANGED
@@ -9,7 +9,10 @@ module Spyke
|
|
9
9
|
delegate :to_ary, :[], :any?, :empty?, :last, :size, :metadata, to: :find_some
|
10
10
|
|
11
11
|
def initialize(klass, options = {})
|
12
|
-
@klass
|
12
|
+
@klass = klass
|
13
|
+
@options = options
|
14
|
+
@params = {}
|
15
|
+
@should_fallback = false
|
13
16
|
end
|
14
17
|
|
15
18
|
def where(conditions = {})
|
@@ -27,6 +30,12 @@ module Spyke
|
|
27
30
|
where
|
28
31
|
end
|
29
32
|
|
33
|
+
def with_fallback(fallback = nil)
|
34
|
+
@should_fallback = true
|
35
|
+
@fallback = fallback
|
36
|
+
where
|
37
|
+
end
|
38
|
+
|
30
39
|
# Overrides Enumerable find
|
31
40
|
def find(id)
|
32
41
|
scoping { klass.find(id) }
|
@@ -34,10 +43,14 @@ module Spyke
|
|
34
43
|
|
35
44
|
def find_one
|
36
45
|
@find_one ||= klass.new_instance_from_result(fetch)
|
46
|
+
rescue ConnectionError => error
|
47
|
+
fallback_or_reraise(error, default: nil)
|
37
48
|
end
|
38
49
|
|
39
50
|
def find_some
|
40
51
|
@find_some ||= klass.new_collection_from_result(fetch)
|
52
|
+
rescue ConnectionError => error
|
53
|
+
fallback_or_reraise(error, default: [])
|
41
54
|
end
|
42
55
|
|
43
56
|
def each(&block)
|
@@ -65,5 +78,17 @@ module Spyke
|
|
65
78
|
ensure
|
66
79
|
klass.current_scope = previous
|
67
80
|
end
|
81
|
+
|
82
|
+
def fallback_or_reraise(error, default:)
|
83
|
+
if should_fallback?
|
84
|
+
@fallback || default
|
85
|
+
else
|
86
|
+
raise error
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def should_fallback?
|
91
|
+
@should_fallback
|
92
|
+
end
|
68
93
|
end
|
69
94
|
end
|
data/lib/spyke/scoping.rb
CHANGED
data/lib/spyke/version.rb
CHANGED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Spyke
|
4
|
+
class FallbacksTest < MiniTest::Test
|
5
|
+
def setup
|
6
|
+
stub_request(:get, "http://sushi.com/recipes/1").to_timeout
|
7
|
+
stub_request(:get, "http://sushi.com/recipes?published=true").to_timeout
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_find_with_default_fallback
|
11
|
+
assert_raises ResourceNotFound do
|
12
|
+
Recipe.with_fallback.find(1)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_find_with_custom_fallback
|
17
|
+
dummy_recipe = Recipe.new(title: "Dummy Recipe")
|
18
|
+
|
19
|
+
result = Recipe.with_fallback(dummy_recipe).find(1)
|
20
|
+
|
21
|
+
assert_equal "Dummy Recipe", result.title
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_find_one_with_default_fallback
|
25
|
+
recipe = Recipe.with_fallback.where(id: 1).find_one
|
26
|
+
|
27
|
+
assert_equal nil, recipe
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_find_some_with_default_fallback
|
31
|
+
assert_equal [], Recipe.where(published: true).with_fallback.all.to_a
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_find_some_with_custom_fallback
|
35
|
+
dummy_result = [Recipe.new(title: "Dummy Recipe")]
|
36
|
+
|
37
|
+
result = Recipe.where(published: true).with_fallback(dummy_result).all
|
38
|
+
|
39
|
+
assert_equal "Dummy Recipe", result.first.title
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spyke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 5.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jens Balvig
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -293,6 +293,7 @@ files:
|
|
293
293
|
- test/attributes_test.rb
|
294
294
|
- test/callbacks_test.rb
|
295
295
|
- test/custom_request_test.rb
|
296
|
+
- test/fallbacks_test.rb
|
296
297
|
- test/orm_test.rb
|
297
298
|
- test/path_test.rb
|
298
299
|
- test/scopes_test.rb
|
@@ -319,7 +320,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
319
320
|
version: '0'
|
320
321
|
requirements: []
|
321
322
|
rubyforge_project:
|
322
|
-
rubygems_version: 2.5.
|
323
|
+
rubygems_version: 2.5.2
|
323
324
|
signing_key:
|
324
325
|
specification_version: 4
|
325
326
|
summary: Interact with REST services in an ActiveRecord-like manner
|
@@ -328,6 +329,7 @@ test_files:
|
|
328
329
|
- test/attributes_test.rb
|
329
330
|
- test/callbacks_test.rb
|
330
331
|
- test/custom_request_test.rb
|
332
|
+
- test/fallbacks_test.rb
|
331
333
|
- test/orm_test.rb
|
332
334
|
- test/path_test.rb
|
333
335
|
- test/scopes_test.rb
|