grape-swagger
grape-swagger copied to clipboard
Singular params with Array[String] in body does not render correct JSON
I hit a bug when trying to use this param declaration:
params do
requires :tags, type: Array[String], documentation: { in: 'body' }
end
Expecting this to create a schema and tag it on the request, it actually did a formData instead:
{
"in": "formData",
"name": "tags",
"type": "array",
"items": {
"type": "string"
},
"required": true
}
I've been using this successfully everywhere else so this threw me off. I experimented and realized that the requires with Array[String] does not work if it's the only one. It immediately works when you add a non array/string param:
params do
requires :tags, type: Array[String], documentation: { in: 'body' }
requires :lol, documentation: { in: 'body' }
end
Results in:
{
"name": "V1PostMortemsReportsReportIdTags",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/putV1PostMortemsReportsReportIdTags"
}
}
And the schema:
{
"type": "object",
"properties": {
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"lol": {
"type": "string"
}
},
"required": [
"tags",
"lol"
],
"description": "Add tags to a report"
}
What's also peculiar is that if you add multiple Array[String] to params it maintains the same bug, I've only been able to get to work the moment you add a non-array param.
This is similar or at least related to https://github.com/ruby-grape/grape-swagger/issues/721.
We hit this again today, where is a good place to look in the code base and provide a fix @dblock ?
I am not sure, @LeFnord might know more.
will have a look on it …
More info about this here: https://github.com/ruby-grape/grape-swagger/issues/721#issuecomment-595958967
I find a PR about my problem, but I don't understand why it is.
created a sample project to check it out … see how_to_array_params it works as expected
@LeFnord I used your sample project, and put some pictures about swagger_ui render, you can see the actual effect. Picture 1 Pitcture 2 It'd submit a array, not like below
{
names: ["aaa", "bbb"]
}
ah, now I see the point …
it will be documented correct as array
"parameters": [
{
"in": "body",
"name": "names",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
}
}
],
but grape accept it only with given name … this way
{
"names": [
"a", "b"
]
}
🤔
ok, checked it … the documentation above is correct and it must be used for body as above, for x-www-form-urlencoded it must be done a similar way via &names[]=a&names[]=b, so it seems the behaviour is correct
ok, checked it … the documentation above is correct and it must be used for
bodyas above, forx-www-form-urlencodedit must be done a similar way via&names[]=a&names[]=b, so it seems the behaviour is correct
You mean that the documentation is correct, and the grape needs to support this form?
I'm facing the same issue with version 1.3.1
optional :booking_ids, type: Array, desc: 'Booking ID of Location'
Generate
curl -X GET ...... -d 'booking_ids=123&booking_ids=456' 'domain/api/v1/locations'
And
optional :booking_ids, type: Array, desc: 'Booking ID of Location', documentation: { param_type: 'body' }
Generate
curl -X GET ...... -d '["81852"]' 'domain/api/v1/locations'
I guest both above are not correct, it should be something like below: (with the [])
curl -X GET ...... -d 'booking_ids[]=123&booking_ids[]=456' 'domain/api/v1/locations'
The issue is with the hack added in #553 that screws up the parameter doc generation.
so it generates swagger docs expecting params of an un-named array. [1,2,3]
If I disable that code, then the docs are still generated incorrectly, as they are generated as an array of objects with an array.
e.g. swagger is expecting this [{booking_ids: [1,2,3]}]
vs. what we all want to happen
{booking_ids: [1,2,3]}
Right now my fix for this issue is to simply turn off this "auto magic" completely as I NEVER use it, and IMHO it should be opt-in.
module GrapeSwagger
module DocMethods
class MoveParams
def self.should_correct_array?(param)
false
end
def self.build_definition(name, _params)
@definitions[name] = object_type
name
end
end
end
end