Kelp::Less - Quick prototyping with Kelp
use Kelp::Less; get '/person/:name' => sub { "Hello " . named 'name'; }; run;
This class exists to provide a way for quick and sloppy prototyping of a web application. It is a wrapper for Kelp, which imports several keywords, making it easier and less verbose to create a quick web app.
It's called Less, because there is less typing involved, and because it is suited for smaller, less complicated web projects. We encourage you to use it anywhere you see fit, however for mid-size and big applications we recommend that you use the fully structured Kelp. This way you can take advantage of its powerful router, initialization and testing capabilities.
Less
Each web app begins with use Kelp::Less;. This automatically imports strict, warnings, v5.10 as well as several useful functions. You can pass any parameters to the constructor at the use statement:
use Kelp::Less;
strict
warnings
v5.10
use
use Kelp::Less mode => 'development';
The above is equivalent to:
use Kelp; my $app = Kelp->new( mode => 'development' );
After that, you could add any initializations and attributes. For example, connect to a database or setup cache. Kelp::Less exports attr, so you can use it to register attributes to your app.
Kelp::Less
# Connect to DBI and CHI right away attr dbh => sub { DBI->connect( @{ app->config('database') } ); }; attr cache => sub { CHI->new( @{ app->config('cache') } ); }; # Another lazy attribute. attr version => sub { app->dbh->selectrow_array("SELECT version FROM vars"); }; # Later: app->dbh->do(...); app->cache->get(...); if ( app->version ) { ... }
Now is a good time to add routes. Routes are added via the "route" keyword and they are automatically registered in your app. A route needs two parameters - path and destination. These are exactly equivalent to "add" in Kelp::Routes, and you are encouraged to read its POD to get familiar with how to define routes. Here are a few examples for the impatient:
path
destination
# Add a 'catch-all-methods' route and send it to an anonymous sub route '/hello/:name' => sub { return "Hello " . named('name'); }; # Add a POST route route [ POST => '/edit/:id' ] => sub { # Do something with named('id') }; # Route that runs an existing sub in your code route '/login' => 'login'; sub login { ... }
Each route subroutine receives $self and all named placeholders.
$self
route '/:id/:page' => sub { my ( $self, $id, $page ) = @_; };
Here, $self is the app object and it can be used the same way as in a full Kelp route. For the feeling of magic and eeriness, Kelp::Lite aliases app to $self, so the former can be used as a full substitute to the latter. See the exported keywords section for more information.
Kelp::Lite
app
After you have added all of your routes, it is time to run the app. This is done via a single command:
run;
It returns PSGI ready subroutine, so you can immediately deploy your new app via Plack:
> plackup myapp.psgi HTTP::Server::PSGI: Accepting connections at http://0:5000/
The following list of keywords are exported to allow for less typing in Kelp::Less:
This a full alias for $self. It is the application object, and an instance of the Kelp class. You can use it for anything you would use $self inside a route.
Kelp
route '/die' => sub { app->res->code(500); };
Assigns lazy or active attributes (using Kelp::Base) to app. Use it to initialize your application.
attr mongo => MongoDB::MongoClient->new( ... );
Adds a route to app. It is an alias to $self->routes->add, and requires the exact same parameters. See Kelp::Routes for reference.
$self->routes->add
route '/get-it' => sub { "got it" };
These are shortcuts to route restricted to the corresponding HTTP method.
route
get '/data' => sub { "Only works with GET" }; post '/data' => sub { "Only works with POST" }; put '/data' => sub { "Only works with PUT" }; del '/data' => sub { "Only works with DELETE" };
An alias for $self->param that gets the GET or POST parameters. When used with no arguments, it will return an array with the names of all http parameters. Otherwise, it will return the value of the requested http parameter.
$self->param
get '/names' => sub { my @names = param; # Now @names contains the names of the params }; get '/value' => sub { my $id = param 'id'; # Now $is contains the value of 'id' };
An alias for $self->stash. The stash is a concept originally conceived by the developers of Catalyst. It's a hash that you can use to pass data from one route to another.
$self->stash
# Create a bridge route that checks if the user is authenticated, and saves # the username in the stash. get '/user' => { bridge => 1, to => sub { return stash->{username} = app->authenticate(); }}; # This route is run after the above bridge, so we know that we have an # authenticated user and their username in the stash. get '/user/welcome' => sub { return "Hello " . stash 'username'; };
With no arguments stash returns the entire stash hash. A single argument is interpreted as the key to the stash hash and its value is returned accordingly.
stash
An alias for $self->named. The named hash contains the names and values of the named placeholders from the current route's path. Much like the stash, with no arguments it returns the entire named hash, and with a single argument it returns the value for the corresponding key in the hash.
$self->named
named
get '/:name/:id' => sub { my $name = named 'name'; my $id = name 'id'; };
In the above example a GET request to /james/1000 will initialize $name with "james" and $id with 1000.
/james/1000
$name
"james"
$id
1000
An alias for $self->req, this provides quick access to the Kelp::Request object for the current route.
$self->req
# Inside a route if ( req->is_ajax ) { ... }
An alias for $self->res, this is a shortcut for the Kelp::Response object for the current route.
$self->res
# Inside a route res->code(403); res->json->render({ message => "Forbidden" });
A shortcut to $self->res->template. Renders a template using the currently loaded template module.
$self->res->template
get '/hello/:name' => sub { template 'hello.tt', { name => named 'name' }; };
Creates and returns a PSGI ready subroutine, and makes the app ready for Plack.
Plack
Loads a Kelp module. The module options may be specified after the module name.
module 'JSON::XS', pretty => 1;
When writing a Kelp::Less app, we don't have a separate class to initialize and feed into a Kelp::Test object, because all of our code is contained in the app.psgi file. In this case, the Kelp::Test object can be initialized with the name of the PSGI file in the psgi argument.
app.psgi
Kelp::Test
PSGI
psgi
# t/main.t use Kelp::Test; my $t = Kelp::Test->new( psgi => 'app.psgi' ); # Do some tests ...
Since you don't have control over the creation of the Kelp object, if you need to specify a different mode for testing, you can use the PLACK_ENV environmental variable:
PLACK_ENV
> PLACK_ENV=test prove -l
This will enable the conf/test.pl configuration, which you should tailor to your testing needs.
conf/test.pl
This module's interface was inspired by Dancer, which in its turn was inspired by Sinatra, so Viva La Open Source!
To install Kelp, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Kelp
CPAN shell
perl -MCPAN -e shell install Kelp
For more information on module installation, please visit the detailed CPAN module installation guide.