Skip to content

Commit f808c48

Browse files
chrisbloom7dblock
authored andcommitted
Allow fallback to use formatter for default format (#34)
1 parent 359298a commit f808c48

File tree

6 files changed

+133
-3
lines changed

6 files changed

+133
-3
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
* Your contribution here.
44

5+
#### v0.5.0
6+
7+
* [#34](https://github.com/ruby-grape/grape-rabl/pulls/34): If no RABL template is specified, fallback to the default response format as determined by Grape - [@chrisbloom7](https://github.com/chrisbloom7).
8+
59
#### v0.4.3
610

711
* [#44](https://github.com/ruby-grape/grape-rabl/issues/44): Don't require unused hashie - [@tsuwatch](https://github.com/tsuwatch).

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ And then execute:
2020

2121
$ bundle
2222

23+
## Upgrading
24+
25+
See [UPGRADING](UPGRADING.md).
26+
2327
## Usage
2428

2529
### Setup view root directory
@@ -134,7 +138,7 @@ class UserAPI < Grape::API
134138
@history = User.find(params[:id]).history
135139
end
136140

137-
# do not use rabl, fallback to the defalt Grape JSON formatter
141+
# do not use rabl, fallback to the default Grape response formatter
138142
get '/users' do
139143
User.all
140144
end

UPGRADING.md

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Upgrading Grape::Rabl
2+
3+
## Upgrading to >= 0.5
4+
5+
### Fallback rendering when no RABL template is defined
6+
7+
Prior to v0.5.0, Grape::Rabl would always render content as JSON when no Rabl template was specified for a request. Beginning in v0.5.0 Grape::Rabl will now fallback to using the default response format [as determined by Grape](https://github.com/ruby-grape/grape#api-formats)
8+
9+
```ruby
10+
class SampleApi < Grape::API
11+
format :xml
12+
formatter :xml, Grape::Formatter::Rabl
13+
14+
get 'list' do
15+
%w[thing]
16+
end
17+
end
18+
```
19+
20+
#### Former behavior
21+
22+
```ruby
23+
response.body # => ["thing"]
24+
```
25+
26+
#### Current behavior
27+
28+
```ruby
29+
response.body # => <?xml version="1.0" encoding="UTF-8"?>\n<strings type="array">\n <string>thing</string>\n</strings>
30+
```
31+
32+
See [#34](https://github.com/ruby-grape/grape-rabl/pull/34) for more information.

lib/grape-rabl/formatter.rb

+7-1
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,18 @@ def render
2929
end
3030
end
3131
else
32-
Grape::Formatter::Json.call object, env
32+
fallback_formatter.call object, env
3333
end
3434
end
3535

3636
private
3737

38+
# Find a formatter to fallback to. `env[Grape::Env::API_FORMAT]` will always be a
39+
# valid formatter, otherwise a HTTP 406 error would have already have been thrown
40+
def fallback_formatter
41+
Grape::Formatter.formatter_for(env[Grape::Env::API_FORMAT])
42+
end
43+
3844
def view_path(template)
3945
if template.split('.')[-1] == 'rabl'
4046
File.join(env['api.tilt.root'], template)

lib/grape-rabl/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Grape
22
module Rabl
3-
VERSION = '0.4.4'.freeze
3+
VERSION = '0.5.0'.freeze
44
end
55
end

spec/grape_rabl_formatter_spec.rb

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
require 'spec_helper'
2+
3+
describe 'Grape::Rabl formatter' do
4+
subject do
5+
Class.new(Grape::API)
6+
end
7+
8+
let(:xml_render) do
9+
%(<?xml version="1.0" encoding="UTF-8"?>
10+
<hash>
11+
<errors type="array">
12+
<error>bad</error>
13+
<error>things</error>
14+
<error>happened</error>
15+
</errors>
16+
</hash>
17+
)
18+
end
19+
20+
def app
21+
subject
22+
end
23+
24+
context 'rendering' do
25+
context 'when no rabl template is specified' do
26+
before do
27+
# Grape::API defaults to the following declarations:
28+
# content_type :xml, 'application/xml'
29+
# content_type :json, 'application/json'
30+
# content_type :binary, 'application/octet-stream'
31+
# content_type :txt, 'text/plain'
32+
# default_format :txt
33+
subject.formatter :xml, Grape::Formatter::Rabl
34+
subject.formatter :txt, Grape::Formatter::Rabl
35+
subject.get('/oops') { { errors: %w[bad things happened] } }
36+
expect_any_instance_of(Grape::Rabl::Formatter).to receive(:render).and_call_original
37+
end
38+
39+
it 'falls back to :txt given no other format information' do
40+
get '/oops'
41+
expect(last_response.body).to eq('{:errors=>["bad", "things", "happened"]}')
42+
expect(last_response.headers['Content-Type']).to eq('text/plain')
43+
end
44+
45+
it 'falls back to the file extension if it is a valid format' do
46+
get '/oops.xml'
47+
expect(last_response.body).to eq(xml_render)
48+
expect(last_response.headers['Content-Type']).to eq('application/xml')
49+
end
50+
51+
it 'falls back to the value of the `format` parameter in the query string if it is provided' do
52+
get '/oops?format=xml'
53+
expect(last_response.body).to eq(xml_render)
54+
expect(last_response.headers['Content-Type']).to eq('application/xml')
55+
end
56+
57+
it 'falls back to the format set by the `format` option if it is a valid format' do
58+
# `format` option must be declared before endpoint
59+
subject.format :xml
60+
subject.get('/oops/2') { { errors: %w[bad things happened] } }
61+
62+
get '/oops/2'
63+
expect(last_response.body).to eq(xml_render)
64+
expect(last_response.headers['Content-Type']).to eq('application/xml')
65+
end
66+
67+
it 'falls back to the `Accept` header if it is a valid format' do
68+
get '/oops', {}, 'HTTP_ACCEPT' => 'application/xml'
69+
expect(last_response.body).to eq(xml_render)
70+
expect(last_response.headers['Content-Type']).to eq('application/xml')
71+
end
72+
73+
it 'falls back to the default_format option if it is a valid format' do
74+
# `default_format` option must be declared before endpoint
75+
subject.default_format :xml
76+
subject.get('/oops/2') { { errors: %w[bad things happened] } }
77+
78+
get '/oops/2'
79+
expect(last_response.body).to eq(xml_render)
80+
expect(last_response.headers['Content-Type']).to eq('application/xml')
81+
end
82+
end
83+
end
84+
end

0 commit comments

Comments
 (0)