Skip to content

Commit 06310eb

Browse files
committed
Merge pull request ruby-grape#180 from bobbytables/json_request_body
Add ability to get request bodies as parameters. Issue ruby-grape#64
2 parents 3ac258c + 6f22b17 commit 06310eb

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

README.markdown

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,19 @@ along with any named parameters you specify in your route strings.
161161
end
162162
```
163163

164+
Parameters are also populated from the request body on POST and PUT for JSON and XML content-types.
165+
166+
The Request:
167+
```curl -d '{"some_key": "some_value"}' 'http://localhost:9292/json_endpoint' -H Content-Type:application/json -v```
168+
169+
170+
The Grape Endpoint:
171+
```ruby
172+
post '/json_endpoint' do
173+
params[:some_key]
174+
end
175+
```
176+
164177
## Headers
165178

166179
Headers are available through the `env` hash object.

lib/grape/endpoint.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,26 @@ def call!(env)
118118
# The parameters passed into the request as
119119
# well as parsed from URL segments.
120120
def params
121-
@params ||= Hashie::Mash.new.deep_merge(request.params).deep_merge(env['rack.routing_args'] || {})
121+
@params ||= Hashie::Mash.new.
122+
deep_merge(request.params).
123+
deep_merge(env['rack.routing_args'] || {}).
124+
deep_merge(self.body_params)
125+
end
126+
127+
# Pull out request body params if the content type matches and we're on a POST or PUT
128+
def body_params
129+
if ['POST', 'PUT'].include?(request.request_method.to_s.upcase)
130+
return case env['CONTENT_TYPE']
131+
when 'application/json'
132+
MultiJson.decode(request.body.read)
133+
when 'application/xml'
134+
MultiXml.parse(request.body.read)
135+
else
136+
{}
137+
end
138+
end
139+
140+
{}
122141
end
123142

124143
# The API version as specified in the URL.

spec/grape/endpoint_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,45 @@ def app; subject end
167167

168168
get '[email protected]/wrong_middle/1'
169169
last_response.status.should == 404
170+
end
171+
end
172+
173+
context 'from body parameters' do
174+
before(:each) do
175+
subject.post '/request_body' do
176+
params[:user]
177+
end
178+
179+
subject.put '/request_body' do
180+
params[:user]
181+
end
182+
end
183+
184+
it 'should convert JSON bodies to params' do
185+
post '/request_body', MultiJson.encode(user: 'Bobby T.'), {'CONTENT_TYPE' => 'application/json'}
186+
last_response.body.should == 'Bobby T.'
187+
end
188+
189+
it 'should convert JSON bodies to params' do
190+
put '/request_body', MultiJson.encode(user: 'Bobby T.'), {'CONTENT_TYPE' => 'application/json'}
191+
last_response.body.should == 'Bobby T.'
192+
end
193+
194+
it 'should convert XML bodies to params' do
195+
post '/request_body', '<user>Bobby T.</user>', {'CONTENT_TYPE' => 'application/xml'}
196+
last_response.body.should == 'Bobby T.'
197+
end
198+
199+
it 'should convert XML bodies to params' do
200+
put '/request_body', '<user>Bobby T.</user>', {'CONTENT_TYPE' => 'application/xml'}
201+
last_response.body.should == 'Bobby T.'
202+
end
170203

204+
it 'does not include parameters not defined by the body' do
205+
subject.post '/omitted_params' do
206+
body_params[:version].should == nil
207+
end
208+
post '/omitted_params', MultiJson.encode(user: 'Blah'), {'CONTENT_TYPE' => 'application/json'}
171209
end
172210
end
173211
end

0 commit comments

Comments
 (0)