NAME
Web::Light - A light weight web framework
VERSION
Version 0.02
SYNOPSIS
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
Description
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.
Usage
new( %args )
Creates a Web::Light instance
- PLUGINS => \@locations
-
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 => [ './' ], );
- NOLOAD => \@list
-
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 /], );
- 404 => $plugin
-
Specify a plugin to handle 404:
new( 404 => 'MyApp::Plugin::My404', );
- AUTH => $plugin
-
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', );
- MOUNT => 'path'
-
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', );
new() Example...
# 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',
);
dispatch( %args )
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.
- root => { plugin => ... }
-
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'.
stash( %args )
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 .. ...),
);
setup( %args )
Define your HTTP::Engine and Middleware preferences here. If no arguments are passed, Web::Light will use ServerSimple and port 5000 by default.
- engine => ( $args )
-
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 => { }, }, }, );
- session => ( $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', }, } } );
- static => ( $args )
-
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/', } );
method_match()
Gets called by dispatch(). This just verifies that the methods you specify in your dispatch map to an actual subroutine.
dispatch_match()
Gets called by dispatch(). This verifies that your dispatch maps to actual plugins
handler()
Handler subroutine sent to HTTP::Engine
createRootPlugin()
Creates the default YourApp::Plugin::Root plugin when called with:
$ perl myapp.pl --create
Creating Plugins
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
Benchmarks
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.
AUTHOR
Michael Kroher, <infrared at cpan.org>
BUGS
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.
See Also
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Web::Light
You can also look for information at:
RT: CPAN's request tracker
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
TO-DO
Not sure yet.
COPYRIGHT & LICENSE
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.