how to develop modern web application framework
Post on 10-May-2015
2.046 Views
Preview:
DESCRIPTION
TRANSCRIPT
Angelos github.com/dann dann
How to developModern WAF
danntechmemo@gmail.com
YAPC::Asia 2009 2009/09/10
Angelos github.com/dann dann
About Me
•Dann
•Creator of Angelos
•Yet Another WAF
•http://github.com/dann/
Angelos github.com/dann dann
Presentation Overview•What is modern web application framework?
•How to develop the minimal elements of modern WAF
•How to develop the plugin architecture of WAF
Angelos github.com/dann dann
What is modern WAF?
•Fullstack like Rails•Pluggable like Plagger•Server Abstraction like WSGI
•Separete WAF and App
Usability
Extendability
Testability
Angelos github.com/dann dann
How to developthe basic elements
of WAF
Angelos github.com/dann dann
The basic elements
ComponentManagerDispatcher
Enginerecieve a request and return a
response(Server Abstraction)
URL to Controller resolver Load and search component
Angelos github.com/dann dann
Basic Sequence of WAF
②①
③
④⑤
⑥
Angelos github.com/dann dann
Engine - Angelos::Engine
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, .... }, psgi_handler => $request_handler, ); } psgi handler which is passed to
the server gateay
the type of server gateway
Angelos github.com/dann dann
Engine - Angelos::PSGI::Engine
use Mouse;use Angelos::Types qw( ServerGateway ); has 'interface' => ( is => 'ro', isa => ServerGateway, coerce => 1,); has 'psgi_handler' => ( is => 'rw', ); sub run { my $self = shift; $self->interface->run( $self->psgi_handler );}
pass psgi handler to server gateway
Create Server Gateway
Angelos github.com/dann dann
Create Server Gateway
package Angelos::PSGI::ServerGatewayBuilder;use strict;use warnings;use Plack::Loader;
sub build { my ( $class, $module, $args ) = @_; my $server_gateway = Plack::Loader->load( $module, %{$args} ); $server_gateway;}
Create server gateway with Plack::Loader
Angelos github.com/dann dann
psgi handler’s code
...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
recieve PSGI envand convert it to WAF Request
Angelos github.com/dann dann
Request Handler - Angelos::Engine::Base
sub handle_request { my ( $self, $req ) = @_;
eval { $self->DISPATCH($req); }; if ( my $e = Exception::Class->caught() ) { $self->HANDLE_EXCEPTION($e); }
# return response return $self->context->res;}
②dispatch request to
Dispatcher
①recive a request
Angelos github.com/dann dann
Dispatchingsub DISPATCH { my ( $self, $req ) = @_;
my $dispatch = $self->dispatcher->dispatch($req); ...
$dispatch->run;
# return response $c->res;}
② Dispatch a request do dispatcher
Angelos github.com/dann dann
Angelos::Dispatchersub dispatch { my ( $self, $request ) = @_;
my $match = $self->router->match($request);
my $dispatch = $self->dispatch_class->new( match => $match ); return $dispatch;}
③ <URL to Controller>search controller name based on the request path with HTTP::Router
④ Create dispatch instance
Angelos github.com/dann dann
Angelos::Dispatcher::Dispatch
my $controller = $match->params->{controller};
my $controller_instance = $self->find_controller_instance( { context => $c, controller => $controller, }); ...
$controller_instance->_dispatch_action( $action, $params );
⑤ search a controller instance from Component Manager
⑥ execute Controller’s action and return response.
Angelos github.com/dann dann
Routing
HTTP::Router->define( sub { $_->match('/')->to( { controller => 'Root', action => 'index' } ); $_->resources('Book'); } );
conf/routes.pl- define routing information
Angelos github.com/dann dann
Routing Table.----------------------------------------------+------------+------------+--------------.| 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
Finished developing basic elements of WAF
•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
How to develop the plugin architecture of WAF
Angelos github.com/dann dann
How to development the plugin architecture of WAF
• 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
The types of Plugins
•Hook WAF’s Lifecycle
•Add methods to WAF’s class
Angelos github.com/dann dann
Plugin Implementation
• 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
How to develop plugin in Angelos
• 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
Hook point example
sub _dispatch_action { my ( $self, $action, $params ) = @_; ...
eval { $self->ACTION( $self->context, $action, $params ); }; ...
}
Declare hook point with Capital character
Angelos github.com/dann dann
the code of Pluginbefore '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 secs\n"; $self->log->info($message);};
Angelos github.com/dann dann
What The WAF developer should do
• 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
Conclusion• 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
Fin.
• It’s really easy to implement WAF now
• Let’s develop modern WAF with us ;)
• Repository
• http://github.com/dann/angelos/tree/master
top related