I'm seeing validation fail on Grape 0.15.0 for parameters which allow multiple types, as shown by the test case below. Replacing [Integer,String] with simply String or Integer works when provided the relevant format.
require 'grape'
class TestAPI < Grape::API
params do
# We originally saw the problem on a JSON parameter, so ensure it applies both on
# that and a normal parameter.
requires :message, type: JSON do
requires :id, type: [Integer,String]
end
requires :id, type: [Integer,String]
end
post do
status 200
{ message_id: params[:message][:id], id: params[:id] }
end
end
run TestAPI
This request will return message[id] is invalid, id is invalid.
POST HTTP/1.1
Host: localhost:9292
Content-Type: application/json
Cache-Control: no-cache
{
"message": "{ \"id\": \"12\" }",
"id": "12"
}
I eventually tracked the problem down to using type rather than types.
While that's clearly user error, and in some ways makes sense, I think its quite easy to miss - is there any way this could be supported without using a different option key?
Yes, would be good to improve this, PR welcome please!
@jellybob @dblock
I don't know if this change is possible. There is distinction between type and types for a purpose. We can have a field with multiple types or a collection with variant type. This behavior is described here
Multiple Allowed Types
Variant-type parameters can be declared using the
typesoption rather thantype:params do requires :status_code, types: [Integer, String, Array[Integer, String]] end get '/' do params[:status_code].inspect end # ... client.get('/', status_code: 'OK_GOOD') # => "OK_GOOD" client.get('/', status_code: 300) # => 300 client.get('/', status_code: %w(404 NOT FOUND)) # => [404, "NOT", "FOUND"]As a special case, variant-member-type collections may also be declared, by
passing aSetorArraywith more than one member totype:```ruby
params do
requires :status_codes, type: Array[Integer,String]
end
get '/' do
params[:status_codes].inspect
end
It would be impossible to guess whether we want a collection or multiple types when we merge those concepts into single keyword. Am I correct?
One way to achieve that is to introduce new type e.g Collection
for fields with multiple types
params do
requires :id, type: [Integer,String]
end
for collections with variant types
params do
requires :ids, type: Collection[Integer, String]
end
But I'm not sure if this is better than types.
Am I misreading this when I say that type: <multiple things> is simply not supported and should error?
Most helpful comment
Am I misreading this when I say that
type: <multiple things>is simply not supported and should error?