khrt / Raisin

Raisin - a REST API micro framework for Perl 🐫 🐪
61 stars 30 forks source link

multiple values for same paramter / ArrayRef[Str] parameters? #25

Closed pryankster closed 7 years ago

pryankster commented 7 years ago

Having a problem with parameters -- if I declare a parameter as ArrayRef[Str], the parser will only see the parameter if there is more than one of them. If I declare a paramter as Str, the parser will not see the parameter unless there is only one.

use strict;
use Data::Dumper;
use warnings;
use FindBin;
use lib ( "$FindBin::Bin/../lib", ".", "$FindBin::Bin/../../Raisin/lib" );

use utf8;

use Raisin::API;
use Types::Standard qw(ArrayRef HashRef Any Int Str);

api_version 0.1;
api_format 'json';

desc 'Items API';
resource items => sub {
    summary 'Query items';
    params(
        optional('a', type => ArrayRef[Str], default => undef,
            desc => 'test arrayref param'),
        optional('s', type => Str, default => undef,
            desc => 'test string')
    );
    get sub {
        my $params = shift;
        my $items = undef;
        my $total = undef;
        print "Params: " . Dumper($params);
    };
};

run;

Queries:

curl 'http://localhost:5000/items?s=s1'

INFO 2016-11-22T15:09:51.790 `a` optional and empty
Params: $VAR1 = {
          's' => 's1'
        };
127.0.0.1 - - [22/Nov/2016:15:09:51 -0800] "GET /items?s=s1 HTTP/1.1" 200 1 "-" "curl/7.47.1
curl 'http://localhost:5000/items?s=s1&s=s2'

INFO 2016-11-22T15:10:32.437 `a` optional and empty
WARN 2016-11-22T15:10:32.439 Param `s` didn't pass constraint `Str` with value "ARRAY(0x2d9fda8)"
Params: $VAR1 = undef;
127.0.0.1 - - [22/Nov/2016:15:10:32 -0800] "GET /items?s=s1&s=s2 HTTP/1.1" 200 1 "-" "curl/7.47.1"
curl 'http://localhost:5000/items?a=a1'

WARN 2016-11-22T15:11:21.090 Param `a` didn't pass constraint `__ANON__` with value "a1"
INFO 2016-11-22T15:11:21.090 `s` optional and empty
Params: $VAR1 = undef;
127.0.0.1 - - [22/Nov/2016:15:11:21 -0800] "GET /items?a=a1 HTTP/1.1" 200 1 "-" "curl/7.47.1"
curl 'http://localhost:5000/items?a=a1&a=a2'

INFO 2016-11-22T15:11:51.596 `s` optional and empty
Params: $VAR1 = {
          'a' => [
                   'a1',
                   'a2'
                 ]
        };
127.0.0.1 - - [22/Nov/2016:15:11:51 -0800] "GET /items?a=a1&a=a2 HTTP/1.1" 200 1 "-" "curl/7.47.1"

Maybe I'm misunderstanding how these parameters should be described?

--pryankster

khrt commented 7 years ago

Looks like a bug, but it needs some time to investigate. Going to be fixed anyway.

Thanks for the report.

khrt commented 7 years ago

It's not a bug.

The first case with (ArrayRef[Str]) When you run a request with only one a specified it is parsed by Plack::Request as a single value, not as an array. With two a specified it is parsed as an array.

The second case (Str) As I described above, it works with one s as it is treated as a single value, and as an array in case of two s and more.

To make it works you can use this command: curl 'http://localhost:5000/items' -X GET -H 'Content-Type: application/json' -d '{"a":["a0","a1"],"s":"str"}'