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!
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

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"
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.