Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

How to develop modern web application framework

on

  • 3,157 views

the slide for YAPC::Asia 2009

the slide for YAPC::Asia 2009

Statistics

Views

Total Views
3,157
Views on SlideShare
3,153
Embed Views
4

Actions

Likes
1
Downloads
15
Comments
0

1 Embed 4

http://www.slideshare.net 4

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

How to develop modern web application framework How to develop modern web application framework Presentation Transcript

  • YAPC::Asia 2009 2009/09/10 dann techmemo@gmail.com Angelos github.com/dann dann
  • • Dann • Creator of Angelos • Yet Another WAF • http://github.com/dann/ Angelos github.com/dann dann
  • Angelos github.com/dann dann
  • Usability Extendability Testability Angelos github.com/dann dann
  • Angelos github.com/dann dann
  • recieve a request and return a Engine response (Server Abstraction) Component Dispatcher Manager URL to Controller resolver Load and search component Angelos github.com/dann dann
  • Angelos github.com/dann dann
  • sub build_engine { my $self = shift; my $request_handler = $self->request_handler; $request_handler ||= $self->build_request_handler; return Angelos::PSGI::Engine->new( interface => { module => $self->server, the type of server .... gateway }, psgi_handler => $request_handler, ); } psgi handler which is passed to the server gateay Angelos github.com/dann dann
  • use Mouse; use Angelos::Types qw( ServerGateway );   has 'interface' => (     is => 'ro', Create Server Gateway     isa => ServerGateway,     coerce => 1, );   pass psgi handler to server has 'psgi_handler' => ( is => 'rw', ); gateway   sub run {     my $self = shift;     $self->interface->run( $self->psgi_handler ); } Angelos github.com/dann dann
  • package Angelos::PSGI::ServerGatewayBuilder; use strict; use warnings; use Plack::Loader; Create server gateway with Plack::Loader sub build { my ( $class, $module, $args ) = @_; my $server_gateway = Plack::Loader->load( $module, %{$args} ); $server_gateway; } Angelos github.com/dann dann
  • recieve PSGI env ... and convert it to WAF Request sub { my $env = shift; my $req = Angelos::Request->new($env); my $res = $self->handle_request($req); my $psgi_res = $self->finalize_response($res); return $psgi_res; } ... return PSGI response Angelos github.com/dann dann
  • recive a request sub handle_request { dispatch request to my ( $self, $req ) = @_; Dispatcher eval { $self->DISPATCH($req); }; if ( my $e = Exception::Class->caught() ) { $self->HANDLE_EXCEPTION($e); } # return response return $self->context->res; } Angelos github.com/dann dann
  • Dispatch a request do sub DISPATCH { dispatcher my ( $self, $req ) = @_; my $dispatch = $self->dispatcher->dispatch($req); ... $dispatch->run; # return response $c->res; } Angelos github.com/dann dann
  • sub dispatch { <URL to Controller> my ( $self, $request ) = @_; search controller name based on the request path with HTTP::Router my $match = $self->router->match($request); my $dispatch = $self->dispatch_class->new( match => $match ); return $dispatch; Create dispatch } instance Angelos github.com/dann dann
  • my $controller = $match->params->{controller}; my $controller_instance = $self- >find_controller_instance( search a controller { context => $c, instance from Component controller => $controller, Manager } ); ... execute Controller’s action and return response. $controller_instance->_dispatch_action( $action, $params ); Angelos github.com/dann dann
  • conf/routes.pl- define routing information HTTP::Router->define( sub { $_->match('/')->to( { controller => 'Root', action => 'index' } ); $_->resources('Book'); } ); Angelos github.com/dann dann
  • .----------------------------------------------+------------+------------+--------------. | path | method | controller | action | +---------------------------------------------+------------+------------+------------+ |/ | | Root | index | | /book.{format} | POST | Books | create | | /book | POST | Books | create | | /book.{format} | GET | Books | index | | /book | GET | Books | index | | /book/new.{format} | GET | Books | post | | /book/new | GET | Books | post | | /book/{book_id}.{format} | GET | Books | show | | /book.{format} | POST | Books | create | | /book | POST | Books | create | | /book.{format} | GET | Books | index | | /book.{bookk_id}.{format} | DELETE | Books | destroy | | /book/{book_id} | DELETE | Books | destroy | | /book/{book_id}.{format} | PUT | Books | update | | /book/{book_id} | PUT | Books | update | '-----------------------------------------------+------------+------------+------------- Angelos github.com/dann dann
  • • It’s really easy to develop basic elements of WAF • You can develop simple WAF like Sinatra in 4 or 5 hours Angelos github.com/dann dann
  • Angelos github.com/dann dann
  • • What the plugin architecture of WAF SHOULD be • The type of Plugins • How to develop plugin architecture of WAF • Example: the plugin of Angelos Angelos github.com/dann dann
  • What the plugin architecture of WAF SHOULD • the core elements of WAF should be as small as possible and the all parts of WAF should be extendable and pluggable • The scope of plugin should be limeted • Controller,View, Middleware, Request, Response • Extension point must be declaretive Angelos github.com/dann dann
  • • Hook WAF’s Lifecycle • Add methods to WAF’s class Angelos github.com/dann dann
  • • Hook WAF’s lifecycle • Mouse’s Role + method modifier • Class::Trigger • MouseX::Object::Pluggable • Add methods to WAF’s classes • Mouse’s Role • Exporter • Multiple inheritance Angelos github.com/dann dann
  • • Make Plugin as Role • User consume plugins in the WAF Component • Hook WAF’s lifecycle with method modifier • hook Component’s hook point • Declare hook point method with CAPITAL character Angelos github.com/dann dann
  • sub _dispatch_action { my ( $self, $action, $params ) = @_;Declare hook point with ... Capital character eval { $self->ACTION( $self->context, $action, $params ); }; ... } Angelos github.com/dann dann
  • before 'ACTION' => sub { my ( $self, $c, $action, $params ) = @_; $self->__action_start_time( time() ); }; after 'ACTION' => sub { my ( $self, $c, $action, $params ) = @_; $self->__action_end_time( time() ); my $elapsed = $self->__action_end_time - $self- >__action_start_time; my $message = "action processing time:naction: $action ntime : $elapsed secsn"; $self->log->info($message); }; Angelos github.com/dann dann
  • • WAF developer should make default plugin sets which user should use • if there aren’t default plugins sets... • How can I use Unicode in WAF? • ... UseXXX,YYY... • How can I inflate datetime? ... Angelos github.com/dann dann
  • • The basic elements of WAF • Engine, Dispatcher, Component Loader • WAF’s plugin • Hook WAF Lifecycle or add a Method to the Component of WAF • Plugin Scope must be limited • the plugin and plugins default sets should be provided by WAF developer Angelos github.com/dann dann
  • • It’s really easy to implement WAF now • Let’s develop modern WAF with us ;) • Repository • http://github.com/dann/angelos/tree/master Angelos github.com/dann dann