Sviluppo web

dall'antichità all'avanguardia e ritorno

Michele Beltrame

Perl.It

---- 1993 ---- Era una notte buia e tempestosa ---- CGI
(NCSA, CERN, ...) ---- C ---- C++ ---- Hmmm ---- * Allocazione memoria * Tipi statici * Limitate librerie text-processing ---- Web
=>
text processing ---- string.h ---- Hmmm ---- Perl ---- # Regular expression if ( $cc =~ /^\d{4}-\d{2}-\d{2}$/ ) # data (migliorabile) } # split, join, ... ---- Codice: mix tra HTML e Perl/C/altro ---- print '<body>'; print '<p>' . $contenuto . '</p>'; ---- Quasi accettabile... ...finché i siti li facevano i programmatori ---- Web designer
Siti più belli... ...a volte ---- Difficoltà di integrazione
print '<ul>'; for my $article (@$articles) { print '<li>'; if ( $article->{id} == $selected_article ) { # Niente CSS fino al 1996 print '<font color="#0000FF">' . $article->{title} . '</font>'; } else { print $article->{title}; } print '</li>'; } print '</ul>'; ---- :-( ---- Poco manutenibile in ogni caso ---- Separare codice HTML da linguaggio scripting ---- Sistemi di templating [% peanut %] [% FOREACH product IN lproducts %]
[% product.name %]
[% END %] ---- HTML dentro linguaggio scripting ---- MALE ---- linguaggio scripting dentro HTML ---- MALE ----

MALE

PHP ---- originariamente scritto in Perl ---- da un tizio per gestire la propria home page ---- Non si può mai sapere come la gente userà ciò che lasci in giro sul web ---- PHP, (some of) the bad * Namespace caotico * Librerie (mysql, mysqli, gd) incluse nel core * Unicode-agnostic * Poco espressivo (per un linguaggio dinamico) * API bizzarra: mysql_escape_string? mysql_real_escape_string?!?! * Ha cresciuto una serie di sviluppatori
...che non pensano che quelli sopra siano problemi
...poco attenti alla sicurezza
---- Ma ---- ---- PHP ha reso il sito web dinamico la norma ---- non è poco ---- e ora anche PHP usa dei sistemi di templating :-) ---- Java ---- Il solo linguaggio per applicazioni web mission-critical ---- ? ---- "vietiamo l'ereditarietà multipla" ---- MI è utile nello 0,0042% dei casi
raccomandare una best practice ma non vietare di ignorarla ---- il codice non sarà manutenibile! ----- brutte cose succederanno al vostro sofware! ---- moriranno dei cuccioli di gatto!!! ---- è giusto vi sia un sentiero consigliato
ma nulla dovrebbe volontariamente essere reso impossibilie ---- Python ---- Attenti agli spazi! Ma è un gran linguaggio ---- 1995 ----

Netscape LiveScript

JavaScript ---- Grande idea Pessimo nome ---- ECMAScript? ---- # Linguaggio ancora poco potente # ma un cambiamento interesante visibility: hidden; display: none; ----

tic tac

... trascorre il Medioevo del web programming ...

tic tac

---- 2004 ---- Web 2.0 ---- Qualunque cosa voglia dire ---- AJAX ---- XMLHttpRequest ---- Possiamo comunicare col server

senza ricaricare la pagina

---- Yay! ---- Talmente semplice e stupido che nessuno ci aveva mai pensato ---- * autocompletamento * form dinamiche * validazione on-the-fly ---- la scalabilità diventa un argomento anche per applicazioni "normali" ---- Ruby ----

Ruby

Ruby on Rails ---- Prime release di Rails * Lento * Scarso supporto Unicode * Leak * Bug vari * Ideale per applicazioni medio-grandi ---- Ma ---- MVC per tutti ---- Esisteva già ma... Rails l'ha fatto conoscere ---- Modern Web Programming ---- Il framework che vanta più tentativi di imitazione ---- Molti dei quali riusciti meglio dell'originale ---- * Django (Python) * Catalyst (Perl) * un'infinità in vari linguaggi ---- Dispatcher avanzati ---- http://mysite.ext/it/products/view/231 http://mysite.ext/en/products/buy/342 ---- it/products/buy/342 # Lingua sub lang : Chained('/') PathPart('') CaptureArgs(1) { my ( $self, $c, $lang ) = @_; # ... } # Prodotti sub products : Chained('lang') PathPart('products') CaptureArgs(0) { my ( $self, $c ) = @_; # ... } # Endpoint 1 sub view : Chained('products') PathPart('view') Args(1) { my ( $self, $c, $id ) = @_; # ... } # Endpoint 2 sub buy : Chained('products') PathPart('buy') Args(1) { my ( $self, $c, $id ) = @_; # ... } ----

mod_rewrite

=> Web-server agnostic ---- Proliferazione di web server piccoli ed efficienti * lighttpd * nginx * ... ---- ORM (Object-Relational Mapper)
una storia di amore e di odio ---- my $rs = $c->model('Dbs::Animali')->search({ 'me.anni' => { '<=' => 4 }, 'razza.nome' => 'beagle', }, { 'join' => 'razza', 'order_by' => 'me.nome', 'rows' => 42, }); select me.* from animali me join razze razza on razza.id = me.idrazza where me.anni <= 4 and razza.nome = 'beagle' order by me.nome limit 42 ---- ~2007 ---- REST ----

HTTP

---- GET /entries/edit?id=42 GET /entries/edit/42 GET /entries/edit?id=42&task=update POST /entries/edit/42 GET /entries/edit/new GET /entries/delete/42 ---- GET /entries/42 POST /entries/42 PUT /entries DELETE /entries/42 ---- <form method="put">
supportato solo in XHTML 2.0 ---- XHTML 2.0??? ---- si usa AJAX ---- AJAJ in realtà ---- JSON ---- la più grande invenzione del web moderno (2005) ---- serializzazione XML * prolissa * poco leggibile ---- standard per serializzare i dati e trasmetterli tra client e server ---- facilmente leggibile dagli umani! ---- HTML 5 ---- Contenitore per vari "standard" (molti dei quali client-side)
ma c'è qualcosa di bello ----

XHTML

---- <br /> => <br> ---- class="miaclasse" => class=miaclasse ---- JavaScript //<![CDATA[ //]]> <!-- --> ---- WebSocket ---- Connessione full-duplex persistente client <=> server ---- Niente più hack: * AJAX polling * Flash (sik) ---- Riduzione overhead per invio di dati => Incremento di velocità di vari ordini di grandezza ---- NodeJS ---- async => prestazioni molto alte rispetto a thread/fork ---- arriva anche negli altri linguaggi ---- Perl ---- Mojolicious ---- framework leggero ---- Sebastian Riedel ---- * un tizio un po' permaloso * un geniale designer di API ---- use Mojolicious::Lite; get '/' => { text => 'Tu sia dannato, Barone Rosso!' }; app->start; Da shell... $ morbo hello.pl Server available at http://127.0.0.1:3000. ---- Deployment: Preforking server FastCGI CGI Plack/PSGI ---- Dispatcher + IO ---- Routes ---- # Regex (overkill) qr|/animali/list/(\d+)| -> $self->render(text => $1); # Route /animali/list/:id -> $self->render(text => $id); # Routes & MVC $r->route('/contatti') ->to(controller => 'pagine', action => 'cont'); ---- # Nested routes (riutilizzo codice) # /animali -> undef # /animali/list -> {controller => 'records', action => 'list'} # /animali/view -> {controller => 'records', action => 'view'} my $foo = $r->route('/animali')->to(controller => 'records'); $foo->route('/list)->to(action => 'list'); $foo->route('/view)->to(action => 'view'); ---- Ai perlisti piace funzionale...
# Closure (callback) $r->route('/animali/cane/abbaia')->to(cb => sub { my $self = shift; $self->render(text => 'Bau'); }); ---- # Placeholder restrittivi $r->route('/animali/:specie') ->to(controller => 'animali', action => 'info'); $r->route('/animali/:specie', specie => ['cane', 'gatto']) ->to(controller => 'animali', action => 'info'); $r->route('/animali/:specie', specie => qr/^leo/) ->to(controller => 'animali', action => 'info'); ---- # HTTP method (REST) $r->route('/animali')->via('GET', 'POST') ->to(controller => 'animali', action => 'info'); $r->route('/animali')->via('DELETE') ->to(controller => 'animali', action => 'delete'); ---- Routes sintetiche (Mojolicious::Lite) ---- Do-What-I-Mean
ma un po' meno assoggettabili al proprio volere ---- get '/animali' => sub { ... } post '/animali' => sub { ... } delete '/animali' => sub { ... } ---- # Formati # /animali -> {controller => 'animali'} # /animali.html -> {controller => 'animali', action => 'info', format => 'html'} # /animali.txt -> {controller => 'animali', action => 'info', format => 'text'} $r->route('/animali')->to(controller => 'animali', action => 'info'); # $format = ... ---- Utili per supportare URL più significative e per inviare risposte diverse in base alla richiesta ---- Risposta in base all'header HTTP ---- Accept: application/json Accept: text/plain ---- get '/list/:offset' => sub { my $self = shift; my $numbers = [42 .. $self->param('offset')]; $self->respond_to( json => {json => $numbers}, txt => {text => join(',', @$numbers)} ); }; ---- JSON ---- post '/update' => sub { my $self = shift; my $chartdata = $self->req->json; # Codice che faccia qualcosa return $self->render_json({ status => 'ok', updated => \@updated, not_updated => \@not_updated, }); } ---- WebSocket ---- # Un semplice pong websocket '/ping' => sub { my $self = shift; # ... async ... $self->on(message => sub { my ($self, $message) = @_; $self->send_message("hai detto: $message"); }); }; ---- Tutta la potenza di CPAN
* ORM: DBIx::Class, Rose::DB::Object, Fey::ORM, ... * Templating: TT, Text::Xslate, HTML::Zoom, ... * Interfacciamento a database * FTP, POP3, SSH, SMTP, IRC, ... * Import/export Excel, CSV, PDF, ... * ritocco immagini, generazione barcode, ... * [molto molto, altro] ---- Molto altro ---- Interessante? ---- Divertente? ---- Mojolicious http://mojolicious.org ----

Cerca anche...

Dancer Catalyst ---- The Perl Foundation Google Code-In * contest per studenti universatari * sviluppo software open source * punti, magliette, soldi, viaggi ---- non in Italia * problemi burocratici :-/ * per ora ---- Grazie! ---- www.perl.it