spyke 4.1.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|