restfulness 0.3.3 → 0.3.4
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 -1
- data/.travis.yml +17 -4
- data/Gemfile.activesupport-4.x +4 -0
- data/Gemfile.activesupport-5.x +4 -0
- data/README.md +46 -6
- data/lib/restfulness/requests/authorization.rb +1 -3
- data/lib/restfulness/resources/events.rb +19 -2
- data/lib/restfulness/response.rb +6 -5
- data/lib/restfulness/version.rb +1 -1
- data/restfulness.gemspec +1 -1
- data/spec/unit/requests/authorization_spec.rb +7 -4
- data/spec/unit/resources/events_spec.rb +31 -13
- data/spec/unit/response_spec.rb +19 -0
- metadata +13 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44dda2a03759ad284a1ab8a77565c243228a4f71
|
4
|
+
data.tar.gz: ef7033d6a4fa26f6918a2c6fbabedf11e866f681
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07f9fadd9d7ac37a8a98a15bb1f1725044804ab4aad388de85399eca7253936167df1533ccd84ff17f2e05aa1122997e336d2dcb1c5aa07ce42c1e03e25d5743
|
7
|
+
data.tar.gz: 56e7173fce55cfc34d2168bbe42ee346fc9357fa5d1fc2438a5e3679df40439f4307f4fa1a1732fcc060eac5198f7306ce9fae0e209bc21d1d74bafea2a161f8
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,10 +1,23 @@
|
|
1
1
|
language: ruby
|
2
|
+
gemfile:
|
3
|
+
- Gemfile.activesupport-4.x
|
4
|
+
- Gemfile.activesupport-5.x
|
2
5
|
rvm:
|
3
|
-
- 2.3.0
|
4
|
-
- 2.2.2
|
5
|
-
- 2.1.5
|
6
6
|
- 2.0.0
|
7
|
-
-
|
7
|
+
- 2.1.10
|
8
|
+
- 2.2.4
|
9
|
+
- 2.3.0
|
10
|
+
- jruby
|
8
11
|
- rbx
|
9
12
|
before_install:
|
10
13
|
- gem install bundler
|
14
|
+
env:
|
15
|
+
- JRUBY_OPTS=--2.0
|
16
|
+
matrix:
|
17
|
+
allow_failures:
|
18
|
+
- rvm: 2.0.0
|
19
|
+
gemfile: Gemfile.activesupport-5.x
|
20
|
+
- rvm: 2.1.10
|
21
|
+
gemfile: Gemfile.activesupport-5.x
|
22
|
+
- rvm: jruby
|
23
|
+
gemfile: Gemfile.activesupport-5.x
|
data/README.md
CHANGED
@@ -414,11 +414,36 @@ By default, any parameter with key prefix `password` will be sanitized in the lo
|
|
414
414
|
Restfulness.sensitive_params = [:password, :secretkey]
|
415
415
|
```
|
416
416
|
|
417
|
-
## Error Handling
|
417
|
+
## Status Code and Error Handling
|
418
418
|
|
419
|
-
If you'd like your application to return anything other than a 200 (or
|
419
|
+
If you'd like your application to return anything other than a 200 status (or 204 for an empty payload), you can set it directly on the response object:
|
420
420
|
|
421
|
-
|
421
|
+
```ruby
|
422
|
+
class ProjectResource < Restfulness::Resource
|
423
|
+
def get
|
424
|
+
response.status = 203
|
425
|
+
project
|
426
|
+
end
|
427
|
+
end
|
428
|
+
```
|
429
|
+
|
430
|
+
The recommended approach in Restfulness however is to use the success status code helpers, for example:
|
431
|
+
|
432
|
+
```ruby
|
433
|
+
class ProjectResource < Restfulness::Resource
|
434
|
+
def get
|
435
|
+
non_authoritative(project) # Respond with 203
|
436
|
+
end
|
437
|
+
def put
|
438
|
+
build_project
|
439
|
+
created(project) # Respond with 201
|
440
|
+
end
|
441
|
+
end
|
442
|
+
```
|
443
|
+
|
444
|
+
Any payload passed into the helper will be returned after setting the code.
|
445
|
+
|
446
|
+
Dealing with error responses (3XX, or 4XX codes) can also be dealt with using the `response` object. Take the following example where we set a 403 response and the model's errors object in the payload:
|
422
447
|
|
423
448
|
```ruby
|
424
449
|
class ProjectResource < Restfulness::Resource
|
@@ -433,7 +458,7 @@ class ProjectResource < Restfulness::Resource
|
|
433
458
|
end
|
434
459
|
```
|
435
460
|
|
436
|
-
|
461
|
+
Continuing from the recommended approach for success helpers, Restfulness provides a `HTTPException` class and "bang" helper methods that will raise the error for you. For example:
|
437
462
|
|
438
463
|
```ruby
|
439
464
|
class ProjectResource < Restfulness::Resource
|
@@ -446,7 +471,7 @@ class ProjectResource < Restfulness::Resource
|
|
446
471
|
end
|
447
472
|
```
|
448
473
|
|
449
|
-
The `forbidden!` bang method will call the `error!` method, which in turn will raise an `HTTPException`
|
474
|
+
The `forbidden!` bang method will call the `error!` method, which in turn will raise an `HTTPException` containing the appropriate status code. Exceptions are permitted to include a payload also, so you can override the `error!` method if you wished with code that will automatically re-format the payload. Another example:
|
450
475
|
|
451
476
|
```ruby
|
452
477
|
# Regular resource
|
@@ -478,7 +503,17 @@ end
|
|
478
503
|
|
479
504
|
This can be a really nice way to mold your errors into a standard format. All HTTP exceptions generated inside resources will pass through `error!`, even those that a triggered by a callback. It gives a great way to provide your own JSON error payload, or even just resort to a simple string.
|
480
505
|
|
481
|
-
The
|
506
|
+
The current built in success methods are:
|
507
|
+
|
508
|
+
* `ok` - code 200, the default.
|
509
|
+
* `created` - code 201.
|
510
|
+
* `accepted` - code 202.
|
511
|
+
* `non_authoritative_information` - code 203.
|
512
|
+
* `non_authoritative` - code 203, same as previous, but a shorter method name.
|
513
|
+
* `no_content` - code 204, default when no payload provided.
|
514
|
+
* `reset_content` - code 205.
|
515
|
+
|
516
|
+
The current built in exception methods are:
|
482
517
|
|
483
518
|
* `not_modified!`
|
484
519
|
* `bad_request!`
|
@@ -671,6 +706,11 @@ Restfulness is still a work in progress but at Cabify we are using it in product
|
|
671
706
|
|
672
707
|
## History
|
673
708
|
|
709
|
+
### 0.3.4 - August 8, 2016
|
710
|
+
|
711
|
+
* Added helper methods for success responses (@samlown)
|
712
|
+
* Don't initialize AuthorizationHeader when authorization is blank. (@arctarus)
|
713
|
+
|
674
714
|
### 0.3.3 - January 19, 2016
|
675
715
|
|
676
716
|
* Basic support for handling large request bodies received as Tempfile (@lauramorillo)
|
@@ -6,7 +6,7 @@ module Restfulness
|
|
6
6
|
def authorization
|
7
7
|
@authorization ||= begin
|
8
8
|
payload = authorization_header_payload
|
9
|
-
AuthorizationHeader.new(payload) unless payload.
|
9
|
+
AuthorizationHeader.new(payload) unless payload.blank?
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -15,8 +15,6 @@ module Restfulness
|
|
15
15
|
def authorization_header_payload
|
16
16
|
headers[:authorization]
|
17
17
|
end
|
18
|
-
|
19
18
|
end
|
20
|
-
|
21
19
|
end
|
22
20
|
end
|
@@ -6,10 +6,20 @@ module Restfulness
|
|
6
6
|
# resources.
|
7
7
|
module Events
|
8
8
|
|
9
|
+
SUCCESS_EVENTS = [
|
10
|
+
[200, :ok],
|
11
|
+
[201, :created],
|
12
|
+
[202, :accepted],
|
13
|
+
[203, :non_authoritative],
|
14
|
+
[203, :non_authoritative_information],
|
15
|
+
[204, :no_content],
|
16
|
+
[205, :reset_content]
|
17
|
+
]
|
18
|
+
|
9
19
|
# Event definitions go here. We only support a limited subset
|
10
20
|
# so that we don't end up with loads of methods that are not used.
|
11
21
|
# If you'd like to see another, please send us a pull request!
|
12
|
-
|
22
|
+
EXCEPTION_EVENTS = [
|
13
23
|
# 300 Events
|
14
24
|
[304, :not_modified],
|
15
25
|
|
@@ -31,7 +41,7 @@ module Restfulness
|
|
31
41
|
raise HTTPException.new(code, payload, opts)
|
32
42
|
end
|
33
43
|
|
34
|
-
|
44
|
+
EXCEPTION_EVENTS.each do |row|
|
35
45
|
define_method("#{row[1]}!") do |*args|
|
36
46
|
payload = args.shift || ""
|
37
47
|
opts = args.shift || {}
|
@@ -39,6 +49,13 @@ module Restfulness
|
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
52
|
+
SUCCESS_EVENTS.each do |row|
|
53
|
+
define_method("#{row[1]}") do |*args|
|
54
|
+
response.status = row[0]
|
55
|
+
return args.first
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
42
59
|
end
|
43
60
|
|
44
61
|
end
|
data/lib/restfulness/response.rb
CHANGED
@@ -52,6 +52,11 @@ module Restfulness
|
|
52
52
|
payload.to_s.bytesize.to_s
|
53
53
|
end
|
54
54
|
|
55
|
+
# Override the status of this response.
|
56
|
+
def status=(code)
|
57
|
+
@status = code.to_i
|
58
|
+
end
|
59
|
+
|
55
60
|
protected
|
56
61
|
|
57
62
|
def resource=(obj)
|
@@ -59,14 +64,10 @@ module Restfulness
|
|
59
64
|
end
|
60
65
|
|
61
66
|
def update_status_and_payload(status, payload = "")
|
62
|
-
self.status = status
|
67
|
+
self.status = status unless self.status.present?
|
63
68
|
self.payload = payload
|
64
69
|
end
|
65
70
|
|
66
|
-
def status=(code)
|
67
|
-
@status = code
|
68
|
-
end
|
69
|
-
|
70
71
|
def payload=(body)
|
71
72
|
if body.nil? || body.is_a?(String)
|
72
73
|
@payload = body.to_s
|
data/lib/restfulness/version.rb
CHANGED
data/restfulness.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "rack", "~> 1.5.0"
|
22
22
|
spec.add_dependency "multi_json", "~> 1.8"
|
23
|
-
spec.add_dependency "activesupport", ">=
|
23
|
+
spec.add_dependency "activesupport", ">= 4.0", "< 6.0"
|
24
24
|
spec.add_dependency "http_accept_language", "~> 2.0"
|
25
25
|
|
26
26
|
spec.add_development_dependency "bundler", "~> 1.3"
|
@@ -14,11 +14,16 @@ describe Restfulness::Requests::Authorization do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
describe "#authorization" do
|
17
|
-
|
18
17
|
it "should be nil if no authorization header resent" do
|
19
18
|
auth = request.authorization
|
20
19
|
expect(auth).to be_nil
|
21
20
|
end
|
21
|
+
|
22
|
+
it "should be nil if authorization header is blank" do
|
23
|
+
request.headers[:authorization] = ""
|
24
|
+
auth = request.authorization
|
25
|
+
expect(auth).to be_nil
|
26
|
+
end
|
22
27
|
|
23
28
|
it "should build new authorization header when present" do
|
24
29
|
request.headers[:authorization] = "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
|
@@ -26,7 +31,5 @@ describe Restfulness::Requests::Authorization do
|
|
26
31
|
expect(auth).to be_a(Restfulness::Requests::AuthorizationHeader)
|
27
32
|
expect(auth.schema).to eql("Basic")
|
28
33
|
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
34
|
+
end
|
32
35
|
end
|
@@ -17,7 +17,6 @@ describe Restfulness::Resources::Events do
|
|
17
17
|
Restfulness::Response.new(request)
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
20
|
describe "#error" do
|
22
21
|
|
23
22
|
class Get418Resource < Restfulness::Resource
|
@@ -35,7 +34,7 @@ describe Restfulness::Resources::Events do
|
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
38
|
-
describe "
|
37
|
+
describe "events" do
|
39
38
|
|
40
39
|
let :klass do
|
41
40
|
Class.new(Restfulness::Resource)
|
@@ -45,24 +44,43 @@ describe Restfulness::Resources::Events do
|
|
45
44
|
klass.new(request, response)
|
46
45
|
end
|
47
46
|
|
48
|
-
|
49
|
-
|
47
|
+
describe "generic bang error events" do
|
48
|
+
it "should support bad_request!" do
|
49
|
+
expect {
|
50
|
+
obj.instance_eval do
|
51
|
+
bad_request!
|
52
|
+
end
|
53
|
+
}.to raise_error(Restfulness::HTTPException, "Bad Request")
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should support bad_request! with paramters" do
|
57
|
+
expect(obj).to receive(:error!).with(400, {:pay => 'load'}, {})
|
50
58
|
obj.instance_eval do
|
51
|
-
bad_request!
|
59
|
+
bad_request!({:pay => 'load'}, {})
|
52
60
|
end
|
53
|
-
|
61
|
+
end
|
54
62
|
end
|
55
63
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
64
|
+
describe "success callbacks" do
|
65
|
+
|
66
|
+
it "should set status for #ok" do
|
67
|
+
obj.instance_eval do
|
68
|
+
no_content
|
69
|
+
end
|
70
|
+
expect(response.status).to eql(204)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should pass through any payload" do
|
74
|
+
payload = "foo"
|
75
|
+
res = nil
|
76
|
+
obj.instance_eval do
|
77
|
+
res = created(payload)
|
78
|
+
end
|
79
|
+
expect(res).to eql(payload)
|
60
80
|
end
|
61
|
-
end
|
62
81
|
|
82
|
+
end
|
63
83
|
|
64
84
|
end
|
65
85
|
|
66
|
-
|
67
|
-
|
68
86
|
end
|
data/spec/unit/response_spec.rb
CHANGED
@@ -32,6 +32,25 @@ describe Restfulness::Response do
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
describe "#status=" do
|
36
|
+
it "should allow status to be forced" do
|
37
|
+
obj.status = 204
|
38
|
+
expect(obj.status).to eql(204)
|
39
|
+
end
|
40
|
+
it "should convert non-integer status to integer" do
|
41
|
+
obj.status = "203"
|
42
|
+
expect(obj.status).to eql(203)
|
43
|
+
end
|
44
|
+
it "should not overwrite on execution" do
|
45
|
+
route = app.router.routes.first
|
46
|
+
allow(request).to receive(:route).and_return(route)
|
47
|
+
allow(request).to receive(:uri).and_return(URI('http://test.com/test'))
|
48
|
+
obj.status = 205
|
49
|
+
obj.run
|
50
|
+
expect(obj.status).to eql(205)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
35
54
|
describe "#run" do
|
36
55
|
context "without route" do
|
37
56
|
it "should not do anything" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: restfulness
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Lown
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -44,14 +44,20 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '4.0'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '6.0'
|
48
51
|
type: :runtime
|
49
52
|
prerelease: false
|
50
53
|
version_requirements: !ruby/object:Gem::Requirement
|
51
54
|
requirements:
|
52
55
|
- - ">="
|
53
56
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
57
|
+
version: '4.0'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '6.0'
|
55
61
|
- !ruby/object:Gem::Dependency
|
56
62
|
name: http_accept_language
|
57
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -118,6 +124,8 @@ files:
|
|
118
124
|
- ".gitignore"
|
119
125
|
- ".travis.yml"
|
120
126
|
- Gemfile
|
127
|
+
- Gemfile.activesupport-4.x
|
128
|
+
- Gemfile.activesupport-5.x
|
121
129
|
- LICENSE.txt
|
122
130
|
- README.md
|
123
131
|
- Rakefile
|
@@ -186,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
194
|
version: '0'
|
187
195
|
requirements: []
|
188
196
|
rubyforge_project:
|
189
|
-
rubygems_version: 2.4.
|
197
|
+
rubygems_version: 2.4.8
|
190
198
|
signing_key:
|
191
199
|
specification_version: 4
|
192
200
|
summary: Use to create a powerful, yet simple REST API in your application.
|