grape-swagger icon indicating copy to clipboard operation
grape-swagger copied to clipboard

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

Open bobbytables opened this issue 7 years ago • 14 comments
trafficstars

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.

bobbytables avatar Nov 05 '18 13:11 bobbytables

This is similar or at least related to https://github.com/ruby-grape/grape-swagger/issues/721.

dblock avatar Nov 07 '18 12:11 dblock

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

bobbytables avatar Jun 18 '19 14:06 bobbytables

I am not sure, @LeFnord might know more.

dblock avatar Jun 18 '19 17:06 dblock

will have a look on it …

LeFnord avatar Jun 19 '19 10:06 LeFnord

More info about this here: https://github.com/ruby-grape/grape-swagger/issues/721#issuecomment-595958967

tristil avatar Mar 06 '20 20:03 tristil

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

oslivan avatar Oct 13 '20 01:10 oslivan

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

LeFnord avatar Oct 13 '20 06:10 LeFnord

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

oslivan avatar Oct 14 '20 10:10 oslivan

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 avatar Oct 14 '20 18:10 LeFnord

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

LeFnord avatar Oct 14 '20 19:10 LeFnord

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?

oslivan avatar Oct 15 '20 09:10 oslivan

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'

thanhnha1103 avatar Jan 11 '21 11:01 thanhnha1103

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 avatar Feb 08 '23 23:02 urkle

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

urkle avatar Feb 09 '23 00:02 urkle