From da10850ed957143ff6f0bd4fa90a30db6b444e3f Mon Sep 17 00:00:00 2001 From: Rawley Date: Mon, 26 Feb 2024 13:48:49 -0600 Subject: [PATCH] add dancer2-controllers article --- dancer2-controllers.html | 72 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 dancer2-controllers.html diff --git a/dancer2-controllers.html b/dancer2-controllers.html new file mode 100644 index 0000000..5135d61 --- /dev/null +++ b/dancer2-controllers.html @@ -0,0 +1,72 @@ + + + + Dancer2::Controllers + + + + +
+ << back +

Dancer2::Controllers and Perl Attributes

+

+ 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. +

+

The approach

+

+ 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. +

+

Speed Bumps

+

+ 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. +

+

In action

+

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 :)

+
+ +