Skip to content

Commit

Permalink
Fix #407: specifying 'default_format' will also set the default POST/…
Browse files Browse the repository at this point in the history
…PUT data parser to the given format.
  • Loading branch information
dblock committed May 20, 2013
1 parent cae92de commit 4aa9ab6
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ Next Release
* [#392](https://github.com/intridea/grape/pull/392): Extracted headers and params from `Endpoint` to `Grape::Request` - [@niedhui](https://github.com/niedhui).
* [#394](https://github.com/intridea/grape/pull/394): Path version no longer overwrites a `version` parameter - [@tmornini](https://github.com/tmornini).
* [#390](https://github.com/intridea/grape/pull/390): Added default value for an `optional` parameter - [@oivoodoo](https://github.com/oivoodoo).
* [#403](https://github.com/intridea/grape/pull/403): Added support for versioning using the `Accept-Version` header - [@politician](https://github.com/politician).
* [#403](https://github.com/intridea/grape/pull/403): Added support for versioning using the `Accept-Version` header - [@politician](https://github.com/politician).
* [#407](https://github.com/intridea/grape/issues/407): Specifying `default_format` will also set the default POST/PUT data parser to the given format - [@dblock](https://github.com/dblock).
* Your contribution here.

0.4.1 (4/1/2013)
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,16 @@ class Twitter::API < Grape::API
end
```

When the content-type is omitted, Grape will return a 406 error code unless `default_format` is specified.
The following API will try to parse any data without a content-type using a JSON parser.

```ruby
class Twitter::API < Grape::API
format :json
default_format :json
end
```

If you combine `format` with `rescue_from :all`, errors will be rendered using the same format.
If you do not want this behavior, set the default error formatter with `default_error_formatter`.

Expand Down
4 changes: 3 additions & 1 deletion lib/grape/middleware/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ def after
# store read input in env['api.request.input']
def read_body_input
if (request.post? || request.put? || request.patch?) &&
(! request.form_data?) && (! request.parseable_data?) &&
(! request.form_data? || ! request.media_type) &&
(! request.parseable_data?) &&
(request.content_length.to_i > 0 || request.env['HTTP_TRANSFER_ENCODING'] == 'chunked')

if env['rack.input'] && (body = (env['api.request.input'] = env['rack.input'].read)).length > 0
Expand All @@ -53,6 +54,7 @@ def read_body_input
def read_rack_input(body)
begin
fmt = mime_types[request.media_type] if request.media_type
fmt ||= options[:default_format]
if content_type_for(fmt)
parser = Grape::Parser::Base.parser_for fmt, options
if parser
Expand Down
32 changes: 32 additions & 0 deletions spec/grape/api_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,15 @@ def self.call(object, env)
end

describe '.parser' do
it 'parses data in format requested by content-type' do
subject.format :json
subject.post '/data' do
{ :x => params[:x] }
end
post "/data", '{"x":42}', { 'CONTENT_TYPE' => 'application/json' }
last_response.status.should == 201
last_response.body.should == '{"x":42}'
end
context 'lambda parser' do
before :each do
subject.content_type :txt, "text/plain"
Expand Down Expand Up @@ -1329,6 +1338,29 @@ def self.call(object, env)
end
end

describe '.default_format' do
before :each do
subject.format :json
subject.default_format :json
end
it 'returns data in default format' do
subject.get '/data' do
{ :x => 42 }
end
get "/data"
last_response.status.should == 200
last_response.body.should == '{"x":42}'
end
it 'parses data in default format' do
subject.post '/data' do
{ :x => params[:x] }
end
post "/data", '{"x":42}', "CONTENT_TYPE" => ""
last_response.status.should == 201
last_response.body.should == '{"x":42}'
end
end

describe '.default_error_status' do
it 'allows setting default_error_status' do
subject.rescue_from :all
Expand Down

0 comments on commit 4aa9ab6

Please sign in to comment.