Skip to content

Commit

Permalink
Merge pull request #180 from bobbytables/json_request_body
Browse files Browse the repository at this point in the history
Add ability to get request bodies as parameters. Issue #64
  • Loading branch information
dblock committed Jun 4, 2012
2 parents 3ac258c + 6f22b17 commit 06310eb
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
13 changes: 13 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ along with any named parameters you specify in your route strings.
end
```

Parameters are also populated from the request body on POST and PUT for JSON and XML content-types.

The Request:
```curl -d '{"some_key": "some_value"}' 'http://localhost:9292/json_endpoint' -H Content-Type:application/json -v```


The Grape Endpoint:
```ruby
post '/json_endpoint' do
params[:some_key]
end
```

## Headers

Headers are available through the `env` hash object.
Expand Down
21 changes: 20 additions & 1 deletion lib/grape/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,26 @@ def call!(env)
# The parameters passed into the request as
# well as parsed from URL segments.
def params
@params ||= Hashie::Mash.new.deep_merge(request.params).deep_merge(env['rack.routing_args'] || {})
@params ||= Hashie::Mash.new.
deep_merge(request.params).
deep_merge(env['rack.routing_args'] || {}).
deep_merge(self.body_params)
end

# Pull out request body params if the content type matches and we're on a POST or PUT
def body_params
if ['POST', 'PUT'].include?(request.request_method.to_s.upcase)
return case env['CONTENT_TYPE']
when 'application/json'
MultiJson.decode(request.body.read)
when 'application/xml'
MultiXml.parse(request.body.read)
else
{}
end
end

{}
end

# The API version as specified in the URL.
Expand Down
38 changes: 38 additions & 0 deletions spec/grape/endpoint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,45 @@ def app; subject end

get 'rodzyn@test.com/wrong_middle/1'
last_response.status.should == 404
end
end

context 'from body parameters' do
before(:each) do
subject.post '/request_body' do
params[:user]
end

subject.put '/request_body' do
params[:user]
end
end

it 'should convert JSON bodies to params' do
post '/request_body', MultiJson.encode(user: 'Bobby T.'), {'CONTENT_TYPE' => 'application/json'}
last_response.body.should == 'Bobby T.'
end

it 'should convert JSON bodies to params' do
put '/request_body', MultiJson.encode(user: 'Bobby T.'), {'CONTENT_TYPE' => 'application/json'}
last_response.body.should == 'Bobby T.'
end

it 'should convert XML bodies to params' do
post '/request_body', '<user>Bobby T.</user>', {'CONTENT_TYPE' => 'application/xml'}
last_response.body.should == 'Bobby T.'
end

it 'should convert XML bodies to params' do
put '/request_body', '<user>Bobby T.</user>', {'CONTENT_TYPE' => 'application/xml'}
last_response.body.should == 'Bobby T.'
end

it 'does not include parameters not defined by the body' do
subject.post '/omitted_params' do
body_params[:version].should == nil
end
post '/omitted_params', MultiJson.encode(user: 'Blah'), {'CONTENT_TYPE' => 'application/json'}
end
end
end
Expand Down

0 comments on commit 06310eb

Please sign in to comment.