Published February 26th, 2024.
Recently I created Dancer2::Controllers
, a simple
Moose
based approach for defining routes in Dancer2. I built this as an attempt to add Spring-Boot esq annotations to
Dancer2.
Perl has a little know feature called "Attributes", which work as some extra arbitrary data appended to
the various reftypes in Perl. When you append an Attribute, Perl looks for the MODIFY_<reftype>_ATTRIBUTES
in the current
namespace, and uses it to decide if that attribute is allowed, and lets you execute some arbitrary code as well. Perl attributes can also take "arguments".
These "arguments" actually are just part of the Attribute, and you need to parse the entire Attribute to get the arguments.
Since Perl Attributes are the closest thing I could find to annotations, I decided a generic Route
attribute would be nice.
With a Perly looking argument pattern: Route(get => /foo)
, this feels a Perl version of Spring-Boot's
@RequestMapping(value = "/foo", method = GET)
,
which is exactly what I was looking for.
Dancer2 is built on-top of Moo
, unfortunately I couldn't find a nice way to handle Attributes using Moo, and inheritance. So, I settled for adding
Moose
and the wonderfully helpful MooseX::MethodAttributes
dist, which drastically simplified the work I needed to do.
The following is an example of how to use Dancer2::Controllers
package My::Controller;
use Moose;
BEGIN { extends 'Dancer2::Controllers::Controller' }
sub home_page : Route(get => /home) {
my $app = shift;
my $user_name = $app->session('user');
return "Welcome back $user_name!";
}
sub home_page : Route(post => /login) {
my $app = shift;
my $password = $app->body_parameters->get('password');
return "Here is your password: $password";
}
1;
package main;
use Dancer2;
use Dancer2::Controllers;
controllers([ 'My::Controller' ]);
dance;
Thanks for reading :)