Search code examples
perlyamlswaggermojolicious

collectionFormat: multi not working with Perl Mojolicious Swagger2


I'm trying to make my API support multiple parameters of the same name: e.g.

/myAPI/search?myfield=1&myfield=2&myfield=3

I'm using Perl and cpan modules Mojolicious and Swagger2

My swagger file (yaml) has this definition (is validated):

/search:
    get:
      x-mojo-controller: "Search"
      operationId: search
      description: Search
      parameters:
        - name: myfield
          description: Array of types
          in: query
          type: array
          collectionFormat: multi
          uniqueItems: true
          items:
            type: string
          required: false

My controller looks like this:

package myAPI::Controller::Search;
use Mojo::Base 'Mojolicious::Controller';
sub search {
    my( $self, $args, $cb ) = @_;
    $self->render(text => Dumper $args);
}

When args are dumped to browser the 'myfield' field appears to be an array, yet it only ever has the last value in it.

$VAR1 = { 'myfield' => [ '3' ] };

Swagger2 version is:

our $VERSION = '0.83';

What am I doing wrong ?


Solution

  • I think you're making your example up or you might have some hooks that mess up the input. The test below runs successfully:

    use Mojo::Base -strict;
    use Test::Mojo;
    use Test::More;
    
    package MyApp::Example;
    use Mojo::Base 'Mojolicious::Controller';
    
    sub search {
      my ($self, $args, $cb) = @_;
      $self->$cb($args, 200);
    }
    
    package main;
    use Mojolicious::Lite;
    plugin Swagger2 => {url => 'data://main/multi-param.json'};
    
    my $t = Test::Mojo->new;
    $t->get_ok('/search?myfield=1&myfield=2&myfield=3')->status_is(200)->json_is('/myfield', [1, 2, 3]);
    
    done_testing;
    
    __DATA__
    @@ multi-param.json
    {
      "swagger": "2.0",
      "info": {"version": "1.0", "title": "Test multi"},
      "paths": {
        "/search": {
          "get": {
            "x-mojo-controller": "MyApp::Example",
            "operationId": "search",
            "parameters": [
              {
                "name": "myfield",
                "in": "query",
                "type": "array",
                "collectionFormat": "multi",
                "uniqueItems": true,
                "items": { "type": "string" },
                "required": false
              }
            ],
            "responses": {
              "200": {"description": "whatever", "schema": {"type": "object"}}
            }
          }
        }
      }
    }
    

    There's already a test for this: https://github.com/jhthorsen/swagger2/blob/master/t/multi-param.t