Grape: Param type Array always rejected as invalid

Created on 6 Jul 2016  路  3Comments  路  Source: ruby-grape/grape

I'm having a lot of trouble with params using the Array datatype with Grape 0.16.2. For example, this API param requirement:

params do
  requires :swipes, type: Array
end

with this input, an array of hashes:

{ "swipes": [ {user_id: 1, other_id: 5}, {user_id: 5, other_id: 2} ] }

produces this error:

{"error":"swipes is invalid"}

However, when I change the param datatype to a Hash, all of a sudden the exact same input (an array of hashes) is accepted and the params are converted into a hash of hashes!

params do
  requires :swipes, type: Hash
end

plus this input:

{ "swipes": [ {user_id: 1, other_id: 5}, {user_id: 5, other_id: 2} ] }

successfully passes the param validations and results in these params:

{ "swipes": { "0": { "user_id": "1", "other_id": "5" }, "1": { "user_id": "5", "other_id": "2" } } }

Am I missing something completely obvious? Thanks!

Most helpful comment

In case anyone runs into this same problem, here's what is happening. Apparently a POST request with an array of JavaScript objects is not valid JSON. Therefore, input that is formatted similarly to my original will fail to pass Grape's Array (and JSON?) validations and result in that cryptic error message. The solution is to covert the array and the objects into strings and then pass that string as the paramters.

So this:

{ "swipes": [ {user_id: 1, other_id: 5}, {user_id: 5, other_id: 2} ] }

should be converted to this:

{ "swipes": '[ {"user_id": 1, "other_id": 5}, {"user_id": 5, "other_id": 2} ]' }

with something like JSON.stringify (if you are using JS).

The reason why changing the expected datatype from an array to a hash results in the exact same (non-string) parameters being accepted appears to be because Rails will coerce the array into a hash before Grape has a chance to validate the parameters.

All 3 comments

What content-type are you sending this as and from where? Usually that's the problem.

I'll close this. Please use the Grape mailing list for questions.

In case anyone runs into this same problem, here's what is happening. Apparently a POST request with an array of JavaScript objects is not valid JSON. Therefore, input that is formatted similarly to my original will fail to pass Grape's Array (and JSON?) validations and result in that cryptic error message. The solution is to covert the array and the objects into strings and then pass that string as the paramters.

So this:

{ "swipes": [ {user_id: 1, other_id: 5}, {user_id: 5, other_id: 2} ] }

should be converted to this:

{ "swipes": '[ {"user_id": 1, "other_id": 5}, {"user_id": 5, "other_id": 2} ]' }

with something like JSON.stringify (if you are using JS).

The reason why changing the expected datatype from an array to a hash results in the exact same (non-string) parameters being accepted appears to be because Rails will coerce the array into a hash before Grape has a chance to validate the parameters.

my params:

      requires :products, type: Array do
        requires :product_id, type: Integer, desc: '鐢㈠搧绶ㄨ櫉'
        requires :product_amount, type: Integer, desc: '鐢㈠搧鏁搁噺'
      end

screen shot 2017-05-09 at 21 59 31

Why I keep getting invalid here?
How should I play with the Swagger UI with array inputs?


And I test with curl, it works with this command:

curl -vX POST http://localhost/api/v1/morders -d "access_token=HzkbszeWYDMAxRZkkqgW \
&products[][product_id]=1&products[][product_amount]=2"
Was this page helpful?
0 / 5 - 0 ratings

Related issues

dblock picture dblock  路  6Comments

stabenfeldt picture stabenfeldt  路  6Comments

nab0310 picture nab0310  路  4Comments

wxianfeng picture wxianfeng  路  8Comments

dblock picture dblock  路  7Comments