Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot PUT/POST a JSON array '[]' #347

Closed
qqshfox opened this issue Feb 24, 2013 · 9 comments
Closed

Cannot PUT/POST a JSON array '[]' #347

qqshfox opened this issue Feb 24, 2013 · 9 comments

Comments

@qqshfox
Copy link
Contributor

qqshfox commented Feb 24, 2013

My config.ru

require 'grape'

class API < Grape::API
  format :json

  post do
    params
  end
end

run API

When I post a array

$ curl -d '[]' -H 'Content-Type: application/json' http://localhost:9292

I got this error:

TypeError: can't convert Array into Hash
    /Users/hanfei/.rvm/gems/ruby-1.9.3-p392@rails/gems/rack-1.4.5/lib/rack/request.rb:221:in `merge'
    /Users/hanfei/.rvm/gems/ruby-1.9.3-p392@rails/gems/rack-1.4.5/lib/rack/request.rb:221:in `params'

Related codes:
https://github.com/intridea/grape/blob/f72135bea37d2d8e5f11f435aa504f4ff7d8a21e/lib/grape/middleware/formatter.rb#L50
https://github.com/rack/rack/blob/7b535cd7ce78eaaaec99cd2677ad8dd5962019a4/lib/rack/request.rb#L225

The RFC says:

2.  JSON Grammar

   A JSON text is a sequence of tokens.  The set of tokens includes six
   structural characters, strings, numbers, and three literal names.

   A JSON text is a serialized object or array.

      JSON-text = object / array

So I think that the '[]' is a valid json syntax.

How can I deal with it with Grape properly? Any help is appreciated.

Thanks,
Hanfei

@dblock
Copy link
Member

dblock commented Feb 25, 2013

I think you're absolutely right. An array is valid JSON. I think you can start by writing some specs and I would begin by trying to open an issue/make a PR into Rack.

@qqshfox
Copy link
Contributor Author

qqshfox commented Feb 25, 2013

Add some specs at #349.

Would you mind taking a quick look at that?

@zeroed
Copy link

zeroed commented Mar 3, 2013

Just a thought ...
I was just looking around about this issue and I found something curious:

https://github.com/zeroed/grape/commit/d45f0b04c411919ebfa5c712246835191332a17e

This solve the specs of qqshfox and breaks others for API.parser...

Obviously it's related with the behaviour of Rack::Rewindableinput

The input stream
...
read behaves like IO#read. Its signature is read([length, [buffer]]). If given, length must be a non-negative Integer > (>= 0) or nil, and buffer must be a String and may not be nil. If length is given and not nil, then this method reads > at most length bytes from the input stream. If length is not given or nil, then this method reads all data until EOF. > When EOF is reached, this method returns nil if length is given and not nil, or "" if length is not given or is nil. If
buffer is given, then the read data will be placed into buffer instead of a newly created String object.

from here

Maybe it's possible to exploit this read/rewind feature... IMVHO.

Bye.

@qqshfox
Copy link
Contributor Author

qqshfox commented Mar 4, 2013

@zeroed Thanks for you attention.

A little clarification at #349.

This just is a quick failed example.
Actually I just don't know how to access the value I put/posted to the api.

BTW You should rewind the input after you read it, or others will not get any data. I think that's why the other specs failed.

@dblock dblock closed this as completed in 6fa8f59 Mar 4, 2013
@dblock
Copy link
Member

dblock commented Mar 4, 2013

I have fixed this in 6fa8f59 and subsequent commits. There're some related changes, the most important one is that for the JSON formatter the response will also now always be valid JSON (eg. strings are returned as "string", not string).

@qqshfox
Copy link
Contributor Author

qqshfox commented Mar 4, 2013

Thanks, will try it as soon as can!

@zeroed
Copy link

zeroed commented Mar 4, 2013

@qqshfox ^_^ ... I know; sorry if my point looked silly... I was just thinking about a workaround using read/rewind ... obviously this 6fa8f59 is the solution... and I will consider it also in my idea of pagination.

Thanks.

@jsilvestri
Copy link

@dblock, I'm curious why you changed strings to be returned as JSON-escaped Strings (change:6fa8f59)? This then fails with the Rabbl presenter as it converts an object to a JSON string, and then the JSON formatter now escapes the JSON in the string

@dblock
Copy link
Member

dblock commented Jul 9, 2013

@jsilvestri Because a string can be represented in JSON format, and returning a string as is, is not valid JSON

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants