| Web-Light documentation | view source | Contained in the Web-Light distribution. |
Version 0.02
Use as a subclass
# myapp.pl
package MyApp;
use base qw/ Web::Light /;
my $app = __PACKAGE__->new();
$app->stash();
$app->dispatch();
$app->setup();
Launch...
$ perl myapp.pl
or
$ perl myapp.pl --help
Web::Light is a light-weight web framework. It's basically just a wrapper around HTTP::Engine and does some stuff to handle plugins. If you are looking for a more tested, developed, and supported web framework, consider using Catalyst.
Web::Light by default launches a stand alone web server that you can connect to with your browser. Since Web::Light can do whatever HTTP::Engine can, you can specify different interfaces like ServerSimple and FastCGI.
Creates a Web::Light instance
Web::Light can load all the modules under $class::* (or MyApp::* in this example). You can specify a list of locations to use when loading modules. The list just gets passed to Module::Find's setmoduledirs() method.
# will default to @INC if PLUGINS is not defined
new(
PLUGINS => [ @INC, './' ],
);
If you don't want to search @INC, and only want to use modules in your current directory, an example of your directory structure might look like this:
$ ls
-rw-r--r-- myapp.pl
drwxr-xr-x MyApp/
drwxr-xr-x MyApp/Plugin
-rw-r--r-- MyApp/Plugin/Root.pm
# then for PLUGINS:
new(
PLUGINS => [ './' ],
);
If there is a module you do not want loaded, you can do this:
new(
PLUGINS => [ @INC, './' ],
NOLOAD => [qw/ MyApp::Plugin::Something MyApp::Foo::Bar /],
);
Specify a plugin to handle 404:
new(
404 => 'MyApp::Plugin::My404',
);
Set the plugin to handle authentication. See dispatch() below on sessions. If a session variable is not set, then the AUTH plugin will be forced.
new(
AUTH => 'MyApp::Plugin::MyAuth',
);
If you are using FastCGI, and wish to have the webserver handle static content, then you can't just Alias / to your application.
Your httpd.conf (Apache) might look like this:
<VirtualHost 192.168.1.100:80>
servername example.org
FastCGIExternalServer /fastcgi -socket /tmp/MyApp.sock
Alias /dynamic /fastcgi/
DocumentRoot /home/user/MyApp/static
</VirtualHost>
With the above example, you would have to mount Web::Light on 'dynamic'
new(
MOUNT => 'dynamic',
);
You cannot mount Web::Light any deeper than one path.
# INVALID!!!
new(
MOUNT => 'site/dynamic',
);
# All together now ...
package MyApp;
use base qw/ Web::Light/;
my $app = __PACKAGE__->new(
PLUGINS => [ @INC, './' , '/path/to/lib' ],
NOLOAD => [ qw/ MyApp::Plugin::OLD MyApp::Auth::File /],
404 => 'MyApp::Plugin::Cool404',
AUTH => 'MyApp::Auth::Awesome',
MOUNT => 'dynamic',
);
Define how URLs get dispatched.
dispatch(
root => {
plugin => 'MyApp::Plugin::Root',
methods => [qw/ default /],
},
home => {
plugin => 'MyApp::Plugin::CoolHome,
methods => [qw/ default test /],
session => [qw/ username /],
},
);
The above example will dispatch the following to the appropriate plugin:
http://localhost/ --> MyApp::Plugin::Root->default()
http://localhost/hello --> MyApp::Plugin::Cool404->default()
http://localhost/home --> MyApp::Plugin::CoolHome->default()
http://localhost/home/test --> MyApp::Plugin::CoolHome->test()
If 'session' contains a list, this forces Web::Light to check if each variable in that list is set. If they aren't, the 'AUTH' plugin that was defined with new() will be forced.
I was going to auto add the 'default' method to the list, but I felt having to specify the methods for each plugin will help remember that this is how it works.
Note: If you do not dispatch a root URL somewhere, Web::Light will set root to dispatch to MyApp::Plugin::Root by default. So either create this plugin:
$ perl myapp.pl --create
... or dispatch root to an already existing plugin:
$app->dispatch(
root => {
plugin => 'MyApp::Foo::Something',
methods => [qw/ default /],
},
);
Also note that root can only have 1 (one) method, and it should be 'default'.
Just a simple hash to pass around stuff to your plugins.
use MyDatabase::Main; # your DBIx::Class
use Template;
my $tt = Template->new;
$app->stash(
tt => $tt,
db => MyDatabase::Main->connect(dbi:mysql .. ...),
);
Define your HTTP::Engine and Middleware preferences here. If no arguments are passed, Web::Light will use ServerSimple and port 5000 by default.
Define HTTP::Engine. Be aware that these settings can be defined on the command line too, like:
$ perl myapp.pl --interface fcgi --nproc 1 --listen /tmp/MyApp.sock --detach
Otherwise, you can specify it like so:
$app->setup(
engine => {
interface => {
module => 'ServerSimple',
args => {
host => '127.0.0.1',
port => 4000,
}
},
}
);
# FastCGI?
$app->setup(
engine => {
interface => {
module => 'FCGI',
args => { },
},
},
);
Define HTTP::Engine::Middleware::HTTPSession
$app->setup(
session => {
store => {
class => 'File',
args => { dir => './tmp' },
},
state => {
class => 'Cookie',
args => {
name => 'MyApp',
path => '/',
domain => 'example.org',
},
}
}
);
Define HTTP::Engine::Middleware::Static to handle your static content
$app->setup(
static => {
regexp => qr{^/(robots.txt|favicon.ico|(?:css|js|images)/.+)$},
docroot => '/home/user/MyApp/',
}
);
Gets called by dispatch(). This just verifies that the methods you specify in your dispatch map to an actual subroutine.
Gets called by dispatch(). This verifies that your dispatch maps to actual plugins
Handler subroutine sent to HTTP::Engine
Creates the default YourApp::Plugin::Root plugin when called with:
$ perl myapp.pl --create
You can name your plugins anything, but in our example, the plugins need to be under MyApp::*
$ mkdir -p MyApp/Foo
$ vi MyApp/Foo/Something.pm
A minimal plugin:
package MyApp::Foo::Something;
sub default {
return "Hello World!";
}
1;
More detailed:
package MyApp::Foo::Something;
use strict;
use warnings;
sub default {
my ($self,$app) = @_;
my $req = $app->{req}; # perldoc HTTP::Engine::Request
my $param = $req->paramenters; # GET/POST paramenters
my $session = $req->session; # perldoc HTTP::Session
my $tt = $app->{stash}{tt}; # Template-Toolkit from your stash
my $schema = $app->{stash}{db}; # your DBIx::Class from your stash
$vars = {
message => "Hello World!",
};
$tt->process('index.tt', $vars, \my $out)
or return $tt->error();
return $out;
}
sub test {
return "Just a test method!";
}
1;
To use this plugin, make sure you dispatch it to a URL...
$app->dispatch(
newplugin => {
plugin => 'MyApp::Foo::Something',
methods => [qw/ default test /],
},
);
Then go to http://localhost/newplugin to see it in action
I've done some quick benchmarking, just to get some frame of reference.
# P3 1.4GHz
# Document Length: 696 bytes
# ab -n 100 -c 2 http://localhost/
FastCGI interface, and Apache handling static content.
---> Requests per second: 171.53 [#/sec] (mean)
ServerSimple interface, serving all content.
---> Requests per second: 180.51 [#/sec] (mean)
*shrug* I'll play around some more. Maybe not.
Michael Kroher, <infrared at cpan.org>
Please report any bugs or feature requests to bug-web-light at rt.cpan.org, or through
the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Web-Light. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
You can find documentation for this module with the perldoc command.
perldoc Web::Light
You can also look for information at:
Not sure yet.
Copyright 2010 Michael Kroher, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Web-Light documentation | view source | Contained in the Web-Light distribution. |