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

Singular params with Array[String] in body does not render correct JSON #725

Open
bobbytables opened this issue Nov 5, 2018 · 14 comments
Open

Comments

@bobbytables
Copy link
Contributor

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.

@dblock
Copy link
Member

dblock commented Nov 7, 2018

This is similar or at least related to #721.

@bobbytables
Copy link
Contributor Author

We hit this again today, where is a good place to look in the code base and provide a fix @dblock ?

@dblock
Copy link
Member

dblock commented Jun 18, 2019

I am not sure, @LeFnord might know more.

@LeFnord
Copy link
Member

LeFnord commented Jun 19, 2019

will have a look on it …

@tristil
Copy link

tristil commented Mar 6, 2020

More info about this here: #721 (comment)

@oslivan
Copy link

oslivan commented Oct 13, 2020

I find a PR about my problem, but I don't understand why it is.

@LeFnord
Copy link
Member

LeFnord commented Oct 13, 2020

created a sample project to check it out … see how_to_array_params it works as expected

@oslivan
Copy link

oslivan commented Oct 14, 2020

@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"]
}

@LeFnord
Copy link
Member

LeFnord commented Oct 14, 2020

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"
  ]
}

🤔

@LeFnord
Copy link
Member

LeFnord commented Oct 14, 2020

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

@oslivan
Copy link

oslivan commented Oct 15, 2020

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

You mean that the documentation is correct, and the grape needs to support this form?

@thanhnha1103
Copy link

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'

@urkle
Copy link
Contributor

urkle commented Feb 8, 2023

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]}

@urkle
Copy link
Contributor

urkle commented Feb 9, 2023

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

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

7 participants