Perl Dancer and defining routes with named parameters and nested prefixes

1.1k views Asked by At

Recently I have been working with Dancer to create a application, but I am having difficulties figuring out how to define the routes.

package MyApp;
use Dancer ':syntax';
our $VERSION = '0.1';

   # Base for routing of requests
   # Match against /:validate

   any '/:validate' => sub {

        # This assumes we can stop the routing here
        # validate the request param in the url string
        # against a regex and 'pass' the request to a
        # specific route with the 'var' option

                var validate => params->{validate};
                .....
                # Validation works and dancer passes successfully
            pass();
   };

   # This is the part that is not working
   prefix '/info' => sub {
       ..... # does stuff
   };    ## back to the root

In the dancer logs for the pass:

[25561] core @0.001133> [hit #1]Last matching route passed! in /usr/local/share/perl5/Dancer/Route.pm l. 216

In the dancer logs for anything after the pass:

[25781] core @0.001524> [hit #4]Trying to match 'GET /11121/info/' against /^/info$/ (generated from '/info') in /usr/local/share/perl5/Dancer/Route.pm l. 84 [25781] core @0.002041> [hit #4]response: 404 in /usr/local/share/perl5/Dancer/Handler.pm l. 179

It is probably something simple I am missing, but I have not had any luck so far. Any help is greatly appreciated.

EDIT I did notice I was using prefix incorrectly so I fixed that and I apologize for the bad explanation. In a nut shell the first part of the url localhost:3000/12/ for example is a database record. All routes are build on that record being the first part of the url string so I want to validate it prior to going any further into the routes.

I was able to setup a before hook which grabs it and can work with the params hash, but it is getting a 500 error on non-matching patterns currently.

        hook before => sub {
            my $route_handler = shift;
            var record => params->{record};

            my $record = var 'record';
            while ($record !~ m/^ID[\-]\d{3,6}$/) {    # Check for valid ID
                    if ($record =~ m/^\d{3,6}$/) {     # Works currently
                            $record = 'ID-'.$record;   
                    }else {forward "/error"};          # this = 500 ISE error
            }
    };

I tried a forward and send_error but both generate an ISE and Dancer reports this on the last entry in the log:

29661] core @0.001048> [hit #2]entering before hook in /usr/local/share/perl5/Dancer/Hook.pm l. 58

Any help is greatly appreciated, also an edit to make my question more clear is welcomed.

2

There are 2 answers

0
Tudor Constantin On BEST ANSWER

I haven't worked with Dancer at all, but from the Dancer::Introduction docs, it looks like you also have to define a route inside the prefix /info. Try with:

# This is the part that is not working
   prefix '/info' => sub {
       get '/' => sub {
          ..... # does stuff
       }
   };    ## back to the root
1
jlareau On

That is not what prefix does. Prefix is used to declare the prefix of the routes in the current package.

prefix '/users';
get '/' => sub { ... };         # matches /users
post '/add' => sub { ... };     # matches /users/add
get '/view/:id' => sub { ... }; # matches /users/view/123