Web::Simple

A Perl Web Nano-Framework

http://cleverdomain.org/wstechtalk/

Another Framework?

Minimal Dependencies

Minimal Apps

Minimal Framework

Really, Really Fast

PSGI Native

Example App

package GuestBook::Web;
use Web::Simple;
use Guestbook;
use JSON::XS 'encode_json';
use Text::Caml;

has 'guestbook' => (is => 'lazy'); sub _build_guestbook { Guestbook->new }
has 'mustache' => (is => 'lazy'); sub _build_mustache { Text::Caml->new }

sub dispatch_request {
  # ...
}
GuestBook::Web->run_if_script;

Example App (contd.)

sub dispatch_request {
  sub (GET + /guestbook) {
    my $self = shift;
    my @messages = $self->guestbook->all_messages;

    sub (.html) {
      [ 200, [ 'Content-Type' => 'text/html' ],
        [ $self->mustache->render_file('guestbook.html', { messages => \@messages }) ]
      ];
    },
    sub (.json) {
      [ 200, [ 'Content-Type' => 'text/json' ],
        [ encode_json(\@messages) ]
      ];
    }
  },
  sub (POST + /guestbook + %:name=&:message=) {
    my $self = shift;
    $self->guestbook->add_message({ name => $_{name}, message => $_{message} });
    [ 302, [ 'Location' => '/guestbook.html' ], [] ];
  }
}

GuestBook Class

package Guestbook;
use Moo;
use MooX::Types::MooseLike::Base ':all';

has messages => (
  is => 'rw',
  isa => ArrayRef,
  lazy => 1,
  default => sub { [] },
);

sub add_message {
  my ($self, $message) = @_;
  push @{$self->messages}, $message;
}

sub all_messages {
  my ($self) = @_;
  return @{$self->messages};
}

1;

Template

<html>
  <head>
    <title>Cool Guestbook</title>
    <link rel="stylesheet" type="text/css" href="/static/style.css">
  </head>
  <body>
    <form method="post">
      <label for="name">Name:</label>
      <input type="text" id="name" name="name">
      <label for="message">Message:</label>
      <textarea name="message" rows="4" cols="80"></textarea>
      <input type="submit">
    </form>
    <hr>
    {{#messages}}
      <div>
        <b>{{name}}:</b> {{message}}
      </div>
    {{/messages}}
    {{^messages}}No messages.{{/messages}}
  </body>
</html>
guestbook.html

What was that sub thing?!

sub (POST + /guestbook + %:name=&:message=) {
  my $self = shift;
  $self->guestbook->add_message({
    name => $_{name},
     message => $_{message},
  });
  [ 302, [ 'Location' => '/guestbook.html' ], [] ];
}

Moo?!

Middleware?

sub dispatch_request {
  sub (GET + /guestbook) {
    # ...
  }
}

Middleware

sub dispatch_request {
  sub (GET) {
    Plack::Middleware::Deflater->new;
  },
  sub (GET + /guestbook) {
    # ...
  }
}

Cool Plack Middlewares

Plack App Dispatch

sub dispatch_request {
  sub (GET + /guestbook) {
    # ...
  },
  sub (/static/...) {
    Plack::App::File->new({ root => '.' })
  }
}

Other Features

Web::Dispatch

Works in Production

Community

IRC: irc.perl.org #web-simple

Demo