Skip to content

Commit 535d43d

Browse files
committed
Allow custom formatters.
1 parent ecfa52b commit 535d43d

File tree

2 files changed

+43
-8
lines changed

2 files changed

+43
-8
lines changed

lib/grape/middleware/formatter.rb

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,26 @@ class Formatter < Base
1111
:rss => 'application/rss+xml',
1212
:txt => 'text/plain'
1313
}
14+
FORMATTERS = {
15+
:json => :encode_json,
16+
:txt => :encode_txt,
17+
}
1418

1519
def default_options
1620
{
1721
:default_format => :txt,
22+
:formatters => {},
1823
:content_types => {}
1924
}
2025
end
2126

2227
def content_types
2328
CONTENT_TYPES.merge(options[:content_types])
2429
end
30+
31+
def formatters
32+
FORMATTERS.merge(options[:formatters])
33+
end
2534

2635
def mime_types
2736
content_types.invert
@@ -75,18 +84,25 @@ def mime_array
7584

7685
def after
7786
status, headers, bodies = *@app_response
78-
bodymap = []
79-
bodies.each do |body|
80-
bodymap << case env['api.format']
81-
when :json
82-
encode_json(body)
83-
when :txt
84-
encode_txt(body)
85-
end
87+
formatter = formatter_for env['api.format']
88+
bodymap = bodies.collect do |body|
89+
formatter.call(body)
8690
end
8791
headers['Content-Type'] = content_types[env['api.format']]
8892
Rack::Response.new(bodymap, status, headers).to_a
8993
end
94+
95+
def formatter_for(api_format)
96+
spec = formatters[api_format]
97+
case spec
98+
when nil
99+
lambda { |obj| obj }
100+
when Symbol
101+
method(spec)
102+
else
103+
spec
104+
end
105+
end
90106

91107
def encode_json(object)
92108
if object.respond_to? :serializable_hash

spec/grape/middleware/formatter_spec.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,23 @@ def serializable_hash
104104
headers['Content-type'].should == 'application/x-custom'
105105
end
106106
end
107+
108+
context 'Format' do
109+
it 'should use custom formatter' do
110+
subject.options[:content_types][:custom] = "don't care"
111+
subject.options[:formatters][:custom] = lambda { |obj| 'CUSTOM FORMAT' }
112+
_, _, body = subject.call({'PATH_INFO' => '/info.custom'})
113+
body.body.should == ['CUSTOM FORMAT']
114+
end
115+
it 'should use default json formatter' do
116+
@body = 'blah'
117+
_, _, body = subject.call({'PATH_INFO' => '/info.json'})
118+
body.body.should == ['"blah"']
119+
end
120+
it 'should use custom json formatter' do
121+
subject.options[:formatters][:json] = lambda { |obj| 'CUSTOM JSON FORMAT' }
122+
_, _, body = subject.call({'PATH_INFO' => '/info.json'})
123+
body.body.should == ['CUSTOM JSON FORMAT']
124+
end
125+
end
107126
end

0 commit comments

Comments
 (0)