Getting started

Punk is an MVC web framework for Perl that resolves and freezes everything - routes, guard chains, handler coderefs, helpers, mounts - once, at to_app time. Nothing is interpreted per request: dispatch is a hash lookup or a short bucket scan, guards are a frozen array walk, and your handler is a plain coderef call receiving one argument, the context.

Install

cpanm Punk

A new application

punk new MyApp
cd MyApp
punk dev

punk new writes a running application - routes, a controller, Stencil views, config/punk.yml, a psgi entry point and a test that starts the app and requests a page. punk dev serves it on Hyperman with restart-on-change.

Have an OpenAPI document already? Point the generator at it and the operations are mounted and stubbed for you, one controller per tag:

punk new MyApp --api ./openapi.json

The application class

use Punk turns on strict and warnings, creates the per-application registry, and exports the DSL keywords into the calling package. An application is a routing table that compiles:

package MyApp;
use Punk;

get  '/'          => 'Web::Book#home';
get  '/books/:id' => 'Web::Book#view';
post '/books'     => 'Web::Book#create';

my $admin = under '/admin' => sub {
    my ($c) = @_;
    return $c->redirect('/') unless $c->req->header('authorization');
    return;
};
$admin->get('/books' => 'Web::Book#admin_list');

static 'https://fal.aihtbprolstatic-tp.hcv9jop5ns4r.cn' => 'root/static';
plugin 'RequestId';

1;
# app.psgi
use MyApp;
MyApp->to_app;

Controller targets like 'Web::Book#view' resolve against MyApp::Controller:: at boot - a typo croaks before the app serves a single request. What boots, serves.

Once it is running

  • punk routes prints the compiled routing table
  • punk doctor reports the environment and C ABIs
  • punk config check resolves the configuration and its secrets
  • punk console opens a REPL with the application compiled

See the CLI recipes for all of them.

Where next