Permalink
Browse files

Fix #347: Grape will accept any valid JSON as PUT or POST, including …

…strings, symbols and arrays. JSON format APIs will always return valid JSON.
  • Loading branch information...
1 parent 0d05c42 commit 6fa8f59e0475f926682168ad4f0bbb2f72df96a3 @dblock dblock committed Mar 4, 2013
View
@@ -2,6 +2,8 @@ Next Release
============
* [#352](https://github.com/intridea/grape/pull/352): Modified registration/execution order of Rack Middleware, fixes issues with `Rack::JSONP` responses that contain a `Grape::Entity` - [@deckchair](https://github.com/deckchair).
+* [#347](https://github.com/intridea/grape/issues/347): Grape will accept any valid JSON as PUT or POST, including strings, symbols and arrays - [@qqshfox](https://github.com/qqshfox), [@dblock](https://github.com/dblock).
+* [#347](https://github.com/intridea/grape/issues/347): JSON format APIs will always return valid JSON, eg. strings are now returned as `"string"` and no longer `string` - [@dblock](https://github.com/dblock).
* Your contribution here.
0.3.2 (2/28/2013)
@@ -4,7 +4,6 @@ module Json
class << self
def call(object, env)
- return object if object.is_a?(String)
return object.to_json if object.respond_to?(:to_json)
MultiJson.dump(object)
end
@@ -44,10 +44,14 @@ def read_body_input
fmt = mime_types[request.media_type] if request.media_type
if content_type_for(fmt)
parser = Grape::Parser::Base.parser_for fmt, options
- unless parser.nil?
+ if parser
begin
- body = parser.call body, env
- env['rack.request.form_hash'] = env['rack.request.form_hash'] ? env['rack.request.form_hash'].merge(body) : body
+ body = (env['api.request.body'] = parser.call(body, env))
+ if body.is_a?(Hash)
+ env['rack.request.form_hash'] = env['rack.request.form_hash'] ? env['rack.request.form_hash'].merge(body) : body
+ else
+ env['api.request.body'] = body
@qqshfox

qqshfox Mar 4, 2013

Contributor

a little dup code?

@dblock

dblock Mar 4, 2013

Owner

Thanks for spotting this. Late night coding, fixed.

+ end
env['rack.request.form_input'] = env['rack.input']
rescue Exception => e
throw :error, :status => 400, :message => e.message
View
@@ -203,13 +203,14 @@ def app; subject end
describe 'root routes should work with' do
before do
+ subject.format :txt
def subject.enable_root_route!
- self.get("/") {"root"}
+ self.get("/") { "root" }
end
end
after do
- last_response.body.should eql 'root'
+ last_response.body.should eql "root"
end
describe 'path versioned APIs' do
@@ -314,16 +315,18 @@ def subject.enable_root_route!
last_response.body.should eql 'hiya'
end
- %w(put post).each do |verb|
- ['string', :symbol, 1, -1.1, {}, [], true, false, nil].each do |object|
- it "allows a(n) #{object.class} json object for #{verb.upcase} when accessing the params" do
- subject.send(verb) do
- params # TODO: get the object passed in
- {}
+ [ :put, :post ].each do |verb|
+ context verb do
+ [ 'string', :symbol, 1, -1.1, {}, [], true, false, nil ].each do |object|
+ it "allows a(n) #{object.class} json object in params" do
+ subject.format :json
+ subject.send(verb) do
+ env['api.request.body']
+ end
+ send verb, '/', MultiJson.dump(object), { 'CONTENT_TYPE' => 'application/json' }
+ last_response.status.should == (verb == :post ? 201 : 200)
+ last_response.body.should eql MultiJson.dump(object)
end
- send verb, '/', MultiJson.dump(object), {'CONTENT_TYPE' => 'application/json'}
- last_response.status.should == (verb == 'post' ? 201 : 200)
- last_response.body.should eql '{}'
end
end
end
@@ -17,7 +17,7 @@ class API < Grape::API
requires :id, :regexp => /^[0-9]+$/
end
post do
- {:ret => params[:id]}
+ { :ret => params[:id] }
end
params do
@@ -60,7 +60,7 @@ def app
it 'does not validate for any params' do
get("/bacons")
last_response.status.should == 200
- last_response.body.should == "All the bacon"
+ last_response.body.should == "All the bacon".to_json
end
it 'validates id' do
@@ -94,7 +94,7 @@ def app
get('/', :name => "Bob", :company => "TestCorp")
last_response.status.should == 200
- last_response.body.should == "Hello"
+ last_response.body.should == "Hello".to_json
end
it 'validates nested parameters' do
@@ -108,7 +108,7 @@ def app
get('/nested', :user => {:first_name => "Billy", :last_name => "Bob"})
last_response.status.should == 200
- last_response.body.should == "Nested"
+ last_response.body.should == "Nested".to_json
end
it 'validates triple nested parameters' do
@@ -138,7 +138,7 @@ def app
get('/nested_triple', :admin => { :admin_name => 'admin', :super => {:user => {:first_name => "Billy", :last_name => "Bob"}}})
last_response.status.should == 200
- last_response.body.should == "Nested triple"
+ last_response.body.should == "Nested triple".to_json
end
end
@@ -1,5 +1,6 @@
shared_examples_for 'versioning' do
it 'sets the API version' do
+ subject.format :txt
subject.version 'v1', macro_options
subject.get :hello do
"Version: #{request.env['api.version']}"
@@ -9,7 +10,8 @@
end
it 'adds the prefix before the API version' do
- subject.prefix 'api'
+ subject.format :txt
+ subject.prefix 'api'
subject.version 'v1', macro_options
subject.get :hello do
"Version: #{request.env['api.version']}"
@@ -58,6 +60,7 @@
context 'with different versions for the same endpoint' do
context 'without a prefix' do
it 'allows the same endpoint to be implemented' do
+ subject.format :txt
subject.version 'v2', macro_options
subject.get 'version' do
request.env['api.version']
@@ -79,7 +82,8 @@
end
context 'with a prefix' do
- it 'allows the same endpoint to be implemented' do
+ it 'allows the same endpoint to be implemented' do
+ subject.format :txt
subject.prefix 'api'
subject.version 'v2', macro_options
subject.get 'version' do

0 comments on commit 6fa8f59

Please sign in to comment.