Mojolicious Routes
This article assumes you are already aware of how to create the Mojolicious app. The most basic Mojolicous routes accept a URI and providing a simple and expressive method of defining routes.
This article assumes you are already aware of how to create the Mojolicious app.
The most basic Mojolicous routes accept a URI and providing a simple and expressive method of defining routes.
package App;
use Mojo::Base 'Mojolicious', -signatures;
# This method will run once at server start
sub startup ($self) {
# Load configuration from config file
my $config = $self->plugin('NotYAMLConfig');
# Configure the application
$self->secrets($config->{secrets});
# Router
my $r = $self->routes;
# Normal route to controller
$r->get('/')->to('Example#welcome');
}
1;
In general, all Mojolicous routes are in your [Your_App].pm files. This Perl package is in the lib directory. We can break this into another file, which we discuss later in the article. Mojolicious loads these routes during the start of the application. Most of the time, we define the routes in Your_App.pm file. We may access the URL by entering it in our browser.
In this example,
$r->get('/')->to('Example#welcome');
Example is the name of the Controller and welcome is the subroutine in it.
Available Routes Methods
We are allowed to register routes that respond to any HTTP queries:
# Normal route to controller
$r->get('/')->to('Example#welcome');
# Post Method
$r->post('/')->('Example#post_welcome');
# Put Method
$r->put('/')->('Example#put_welcome');
# Any Method
$r->any('/')->('Example#any_welcome');
# Patch Method
$r->patch('/')->('Example#path_welcome');
# Remove method
$r->find('/route_to_remove')->remove;
# GET|POST Only
$r->any(['GET', 'POST'] => '/get_post_only')->to('Example#get_post_welcome');
Dynamic Routes
While developing the application, we need to know the parts of the URI within the route. For example, we may need to obtain a post id from the URL.
$r->get('/blog/:post_id')->to('Blog#post_view');
We can define as many route parameters or placeholders in the Mojolicious routes.
Conventional dynamic route parameters start with ":" and consist of alphabetic characters. Underscores (_) are also acceptable within route parameter names.
Placeholders in Dynamic Routes
Placeholders use a colon prefix and match all characters except /
and .
, similar to the regular expression.
$r->get('/user/:id')->to('User#user_details', id => '1');
In the above example, we are passing the value of id (1) to the controller.
We can also restrict the value of ids to be passed to the controller.
$r->get('/user/:id' => [id => ['1', '2']])->to('User#user_details');
Prefixing Route
Prefix a route or nested routes are not uncommon in web applications. For example, if a web application has an admin interface, all the URLs start with /admin word. It's not mandatory though good to follow this practice.
my $admin = $r->any('/admin')->to(controller => 'Admin', action -> 'default');
$admin->get('/login')->to(action -> 'login');
$admin->post('/login')->to(action -> 'login_post');
$admin->get('/dashboard')->to(action -> 'dashboard');
Protecting a Route
Sometimes, routes need to be protected like the user profile.
sub startup ($self) {
# ........
# Somewhere in the startup subroutine add
$self->_add_routes_authorization();
# User Profile
$r->get('/user/profile')->requires( user_authenticated => 1 )->to('User#show_profile');
# .........
}
sub _add_routes_authorization {
my $self = shift;
$self->routes->add_condition(
user_authenticated => sub {
my ( $r, $c ) = @_;
return $c->redirect_to(
'/auth/signin?redirect=' . $c->req->headers->referrer
);
# See Login using Mojolicious for this piece of code
if ( !defined( $c->session('user_exists') ) ) ;
return 1;
}
}
In the above case, if user_authenticated variable is not equal to 1 it'll redirect to signin page.
Prefixing Routes
Prefixing or Route groups allow you to share route attributes without redefining those attributes on each individual route. For example, you may want to prefix all route URIs within the group with the admin.
$r->add_shortcut(resource => sub ($r, $name) {
# Prefix for resource
my $resource = $r->any("/$name")->to("$name#");
# Admin Dashboard GET /admin/dashboard
$resource->get('/dashboard')->to('#dashboard')->name($name);
# /admin/user to list all users
# GET /admin/user
$resource->get('/user')->to('#user')->name("list_user");
# show a specific user
# GET /admin/user/:id
$resource->get('/user/:id')->to('#show')->name("show_user");
# Render a form to edit a user information
# GET /admin/user/:id/edit
$resource->get('/user/:id/edit')->to('#edit')->name("edit_user");
# Store updated user information
# POST /admin/user/:id
$resource->put('/user/:id')->to('#update')->name("update_user");
# Delete a resource
# Delete /admin/user/:id
$resource->delete('/user/:id')->to('#remove')->name("delete_user");
return $resource;
});
$r->resource('admin');
AK Newsletter
Join the newsletter to receive the latest updates in your inbox.