• Like

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.

How to develop modern web application framework

  • 1,997 views
Uploaded on

the slide for YAPC::Asia 2009

the slide for YAPC::Asia 2009

More in: Technology , Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,997
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
15
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. YAPC::Asia 2009 2009/09/10 dann techmemo@gmail.com Angelos github.com/dann dann
  • 2. • Dann • Creator of Angelos • Yet Another WAF • http://github.com/dann/ Angelos github.com/dann dann
  • 3. Angelos github.com/dann dann
  • 4. Usability Extendability Testability Angelos github.com/dann dann
  • 5. Angelos github.com/dann dann
  • 6. 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
  • 7. Angelos github.com/dann dann
  • 8. 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
  • 9. 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
  • 10. 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
  • 11. 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
  • 12. 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
  • 13. 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
  • 14. 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
  • 15. 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
  • 16. conf/routes.pl- define routing information HTTP::Router->define( sub { $_->match('/')->to( { controller => 'Root', action => 'index' } ); $_->resources('Book'); } ); Angelos github.com/dann dann
  • 17. .----------------------------------------------+------------+------------+--------------. | 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
  • 18. • 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
  • 19. Angelos github.com/dann dann
  • 20. • 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
  • 21. 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
  • 22. • Hook WAF’s Lifecycle • Add methods to WAF’s class Angelos github.com/dann dann
  • 23. • 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
  • 24. • 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
  • 25. 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
  • 26. 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
  • 27. • 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
  • 28. • 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
  • 29. • 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