I am reading the section of Mojolicious::Guides::Growing where it tells you how to grow a Mojolicious::Lite into a "well organized" cpan-uploadable application. First, it tells you to split the M::L app into a launch script and an application class.
package MyApp;
use Mojo::Base 'Mojolicious';
use MyUsers;
sub startup {
my $self = shift;
# ...auth stuff omitted...
my $r = $self->routes;
$r->any('/' => sub {
my $self = shift;
my $user = $self->param('user') || '';
my $pass = $self->param('pass') || '';
return $self->render unless $self->users->check($user, $pass);
$self->session(user => $user);
$self->flash(message => 'Thanks for logging in.');
$self->redirect_to('protected');
} => 'index');
$r->get('/protected' => sub {
my $self = shift;
return $self->redirect_to('index') unless $self->session('user');
});
$r->get('/logout' => sub {
my $self = shift;
$self->session(expires => 1);
$self->redirect_to('index');
});
}
1;
This makes sense to me. But then it goes on to say that this application class can further be refactored into a controller class with the actions, and the application class itself can be reduced to the routing information:
package MyApp::Login;
use Mojo::Base 'Mojolicious::Controller';
sub index {
my $self = shift;
my $user = $self->param('user') || '';
my $pass = $self->param('pass') || '';
return $self->render unless $self->users->check($user, $pass);
$self->session(user => $user);
$self->flash(message => 'Thanks for logging in.');
$self->redirect_to('protected');
}
sub protected {
my $self = shift;
return $self->redirect_to('index') unless $self->session('user');
}
sub logout {
my $self = shift;
$self->session(expires => 1);
$self->redirect_to('index');
}
1;
package MyApp;
use Mojo::Base 'Mojolicious';
use MyUsers;
sub startup {
my $self = shift;
# ...auth stuff omitted...
my $r = $self->routes;
$r->any('/')->to('login#index')->name('index');
$r->get('/protected')->to('login#protected')->name('protected');
$r->get('/logout')->to('login#logout')->name('logout');
}
1;
I don't see why this is superior to the "hybrid" version where routes and actions are intermingled, because now in order to redirect between the actions with redirect_to() in the controller, you need to look at the routing infomration in a different file, and if you want to change a url, you have to do it in two different files instead of one. This:
$r->get('/protected' => sub {
my $self = shift;
return $self->redirect_to('index') unless $self->session('user');
});
turns into:
sub protected {
my $self = shift;
return $self->redirect_to('index') unless $self->session('user');
}
$r->get('/protected')->to('login#protected')->name('protected');
Which has the word "protected" 4 times in two different files (although I'm not sure what the name("protected") does yet).
I'm a complete novice when it comes to web development, by the way.