Sawyer X

NAME

Dancer2::Plugin::ParamTypes - Parameter type checking plugin for Dancer2

VERSION

version 0.002

SYNOPSIS

    package MyApp;
    use Dancer2;
    use Dancer2::Plugin::ParamTypes;

    # First we define some type checks
    # Read below for explanation
    register_type_check 'Int' => sub {...};
    register_type_check 'Str' => sub {...};

    get '/:id' => with_types [
        # Required
        [ 'route', 'id',  'Int' ],
        [ 'query', 'num', 'Int' ],

        # Optional, either as query or body
        'optional' => [ [ 'query', 'body' ], 'name', 'Str' ],
    ] => sub {
        my $id  = route_parameters->{'id'};
        my @num = query_parameters->get_all('num');
        ...
    };

    # If we define our own action
    register_type_action 'SpecialError' => sub {...};

    # We can now use it in the type check
    get '/' => with_types [
        [ 'query', 'id', 'Int', 'SpecialError' ]
    ] => sub {
        ...
    };

DESCRIPTION

This is a simple module that allows you to provide a stanza of parameter type checks for your routes.

It supports all three possible sources: route, query, and body.

Currently no types are available in the system, so you will need to write your own code to add them. See the following methods below.

Methods

register_type_check

First you must register a type check, allowing you to test stuff:

    register_type_check 'Int' => sub {
        return Scalar::Util::looks_like_number( $_[0] );
    };

register_type_action

    register_type_action 'MyError' => sub {
        my ( $self, $details ) = @_;

        my $source = $details->{'source'};
        my $name   = $details->{'name'};
        my $type   = $details->{'type'};
        my $action = $details->{'action'};

        send_error("Type check failed for $name ($type)");
    }

with_types

with_types defines checks for parameters for a route request.

    get '/:name' => with_request [

        # Basic usage
        [ SOURCE, NAME, TYPE ]

        # Provide a custom action
        [ SOURCE, NAME, TYPE, ACTION ]

        # Provide multiple sources (either one will work)
        [ [ SOURCE1, SOURCE2 ], NAME, TYPE ],

        # Optional type check
        # (if available will be checked, otherwise ignored)
        'optional' => [ SOURCE, NAME, TYPE ]

    ] => sub {
        ...
    };

Above are all the options, but they will also work in any other combination.

Connecting existing type systems

Because each type check is a callback, you can connect these to other type systems:

    register_type_check 'Str' => sub {
        require MooX::Types::MooseLike::Base;

        # This call will die when failing,
        # so we put it in an eval
        eval {
            MooX::Types::MooseLike::Base::Str->( $_[0] );
            1;
        } or return;

        return 1;
    };

Creating your own pre-defined type checks

The following is a simple example of introducing a subclass of this plugin in order to create your own version with pre-defined checks.

    package Dancer2::Plugin::MyParamTypes;
    use strict;
    use warnings;
    use Dancer2::Plugin;

    # subclass
    extends('Dancer2::Plugin::ParamTypes');

    # define our own plugin keyword
    plugin_keywords('with_types');

    # which simply calls the parent
    sub with_types {
        my $self = shift;
        return $self->SUPER::with_types(@_);
    }

    sub BUILD {
        my $self = shift;

        # register our own type checks
        $self->register_type_check(
            'Int' => sub { Scalar::Util::looks_like_number( $_[0] ) },
        );
    }

Later, the application can simply use this module:

    package MyApp;
    use Dancer2;
    use Dancer2::Plugin::MyParamTypes;

    get '/' => with_types [
        [ 'query', 'id', 'Int' ],
    ] => sub {...};

AUTHOR

Sawyer X

COPYRIGHT AND LICENSE

This software is Copyright (c) 2016 by Sawyer X.

This is free software, licensed under:

  The MIT (X11) License