Can I make swagger-php use arrays on the query string?
Asked Answered
T

8

8

I use Swagger-php. When I define a parameter that's on the query string it can be an array. But from what I can see, it doesn't support this kind of querystring:

https://api.domain.tld/v1/objects?q[]=1&q[]=5&q[]=12

I believe this would be set in the collectionFormatfield if possible. Currently I've just been using pipes, but I want to use the above format, and have Swagger-UI reflect this, too. However, I read this github issue which has left me wondering if this is actually possible and I've just missed it?

An example of my Swagger-PHP definition:

/**
*     @SWG\Parameter(
*         name="ids",
*         in="query",
*         description="A list of IDs (separated by pipes) to filter the Returns",
*         required=false,
*         type="array",
*         @SWG\Items(
*             type="integer",
*             format="int32"
*         ),
*         collectionFormat="pipes"
*     )
*/

Which results in the following JSON:

"parameters": {
    "ids": {
        "name": "ids",
        "in": "query",
        "description": "A list of IDs (separated by pipes) to filter the Returns",
        "required": false,
        "type": "array",
        "items": {
            "type": "integer",
            "format": "int32"
        },
        "collectionFormat": "pipes"
    }
}
Tipper answered 17/6, 2016 at 9:31 Comment(0)
I
2

Its now possible to do this without [] hack of most liked answer. Use the deepObject style.

 name: q
 style: deepObject
 schema:
   type: array
   items:
     type: string

This will generate an url like following: q[0]=string1&q[1]=string2

Intrepid answered 25/11, 2019 at 15:6 Comment(2)
deepObject style is not defined for arrays, it's only defined for objects. So this answer is not OpenAPI-compliant. As of March 2021 / OpenAPI 3.1, the correct solution is still to use a parameter named q[], like shown in Ima's answer.Torrential
q[] won't generate q[0]=string1&q[1]=string2 but q[]=string1&q[]=string2 so the former is simply not possible yetDoornail
P
14
/**
 *     @SWG\Parameter(
 *         name="q[]",
 *         in="query",
 *         description="A list of IDs (separated by new lines) to filter the Returns",
 *         required=false,
 *         type="array",
 *         collectionFormat="multi",
 *         uniqueItems=true,
 *     )
 */

This will result in something similiar to this

{
    "name": "q[]",
    "in": "query",
    "description": "type",
    "required": false,
    "type": "array",
    "collectionFormat": "multi",
    "uniqueItems": true
}

Resulting image

Pasquil answered 18/4, 2017 at 7:9 Comment(2)
This should be the answer. I have spent a few hours searching for answers and as the current answer says, only multi, csv, ssv or tsv are accepted, but adding brackets to the name works with multi. There's no website, blog, or documentation for this case except this comment.Brahmanism
Check following for solution without [] hack: https://mcmap.net/q/1248553/-can-i-make-swagger-php-use-arrays-on-the-query-stringIntrepid
M
4

If you haven't already I'd suggest trying the following:

*      @OA\Parameter(
*          name="category[]",
*          description="array of category numbers",
*          in="query",     
*          @OA\Schema( 
*              type="array", 
*              @OA\Items(type="enum", enum={1,2,3,4,5,6,7,8,9}),
*              example={1,2} 
*          )
*      ),

I modified this to fit my use-case:

*    @OA\Parameter(
*      name="things[]",
*      in="query",
*      description="A list of things.",
*      required=false,
*      @OA\Schema(
*        type="array",
*        @OA\Items(type="integer")
*      )
*    ),

Source: https://github.com/zircote/swagger-php/issues/612#issue-380202012

Mysia answered 15/7, 2019 at 9:42 Comment(0)
D
2

Please go through this; this is work for me

 /**
 *     @SWG\Parameter(
 *         name="id[]",
 *         in="query",
 *         description="A list of IDs (separated by new lines) to filter 
            the Returns",
 *         required=false,
 *         type="array",
 *         collectionFormat="multi",
 *        @SWG\Items(
 *             type="integer",
 *             format="int32"
 *         ),
 *         uniqueItems=true,
 *     )
 */
Dumbhead answered 4/6, 2018 at 11:28 Comment(0)
I
2

Its now possible to do this without [] hack of most liked answer. Use the deepObject style.

 name: q
 style: deepObject
 schema:
   type: array
   items:
     type: string

This will generate an url like following: q[0]=string1&q[1]=string2

Intrepid answered 25/11, 2019 at 15:6 Comment(2)
deepObject style is not defined for arrays, it's only defined for objects. So this answer is not OpenAPI-compliant. As of March 2021 / OpenAPI 3.1, the correct solution is still to use a parameter named q[], like shown in Ima's answer.Torrential
q[] won't generate q[0]=string1&q[1]=string2 but q[]=string1&q[]=string2 so the former is simply not possible yetDoornail
U
1

Unfortunately, it is not possible to get exactly the URL you provide (https://api.domain.tld/v1/objects?q[]=1&q[]=5&q[]=12) for an array query parameter.

Assuming that you want to define a 1 dimension array query parameter (the github issue you're refering to concerns multi-dimensional arrays), here's what the current OpenAPI (fka. Swagger) Specification can propose:

  • If you use an array with a collection format like pipes (you can also use csv, ssv or tsv to get different separators) the URL will look like this:

    https://api.domain.tld/v1/objects?q=1|5|12
    

    But this is not the syntax you're looking for: all array items are defined in a single q query parameter.

  • Fortunately, there is another collection format multi allowing to define each array's item in its own q parameter, with this one you can almost get what you want minus the []:

    https://api.domain.tld/v1/objects?q=1&q=5&q=12
    

You can read more about this in this OpenAPI (fka. Swagger) tutorial (disclosure: I wrote it) and in the specification itself (ParameterObject description)

Umlaut answered 18/6, 2016 at 16:23 Comment(2)
Thanks @Arnaud. I considered multi but with PHP you would get just the last value unfortunately, so I've decided to go with pipes after all. Nice tutorial by the way :)Tipper
Check following how to do it without a hack: https://mcmap.net/q/1248553/-can-i-make-swagger-php-use-arrays-on-the-query-stringIntrepid
L
1

As of OpenAPI 3.0, the following should work:

/**
 * @OA\Parameter(
 *     name="category[]",
 *     description="array of category numbers",
 *     in="query",     
 *     @OA\Schema( 
 *         type="array", 
 *         @OA\Items(type="enum", enum={1,2,3,4,5,6,7,8,9}),
 *         example={1,2} 
 *     ),
 *     allowedReserved=true
 * ),
 */

allowedReserved prevents [] in name from being encoded into %5B%5D

According to official doc

The default serialization method is style: form and explode: true. This corresponds to collectionFormat: multi from OpenAPI 2.0.

collectionFormat: multi is not required anymore.

You may write it as attribute as well:

new OA\Parameter(
    in: 'query',
    name: 'category[]',
    schema: new OA\Schema(
        type: 'array',
        items: new OA\Items(
            type: 'enum',
            enum: [1,2,3,4,5,6,7,8,9]
        ),
    ),
    description: 'array of category numbers',
    allowReserved: true
),
Livonia answered 2/7 at 17:59 Comment(0)
T
0

Disclaimer: im using SwaggerUI, but this might work for you as well.

I was also wondering about this for some time, but i decided to go through the js code and see if i can change/fix it there and i noticed these few lines of code:

if (type === 'brackets' || type === 'multi') {
    var bracket = type === 'brackets' ? '[]' : ''
    for (var i = 0; i < value.length; i++) {
        if (i > 0) {encoded += '&';}

        encoded += this.encodeQueryParam(name) + bracket + '=' + this.encodeQueryParam(value[i]);
    }
}

So it seems there is a collectionFormat 'brackets' that was not defined in the OpenAPI v2 specification. Tried it out and it seems to be working.

Tetrahedral answered 20/10, 2016 at 6:42 Comment(0)
B
0

Following code works fine: See the ScreenShot

'"parameters": [

      {

        "name": "fav",

        "description": "Enter ids of Favoruite",

        "in": "formData",

        "type": "array",

        "items": {

          "type": "integer",

          "format": "int32"

        },

        "paramType": "form",

        "required": true

      }],'
Bautista answered 3/12, 2018 at 4:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.