L’ambarasgnao

Dopo la pubblicazione del mio articolo sui Web Framework, uno dei miei amici e colleghi (che di solito si occupa d’altro…) mi ha chiesto: “OK, è tutto molto interessante ma… in pratica, come funziona tutto l’ambarasgnao?”

Qui di seguito la mia risposta.

La materia prima: i web toolkit

Per capire come è fatto e come funziona un web framework, bisogna partire dai suoi componenti. Quasi tutti i web framework, infatti, hanno visto la luce prima di tutto come collezione organizzata di strumenti (“toolbox” o “toolkit”) e solo in un secondo momento sono stati dotati delle funzionalità tipiche di un sistema autonomo e completo.

Adapter

Tutta la programmazione web gira attorno ad un concetto di base molto semplice ma dalle conseguenze molto importanti: in un modo o nell’altro, l’applicazione web deve comunque ricevere una richiesta HTTP dal web server e deve comunque fornirgli una risposta HTTP. Questi due “oggetti logici” sono degli insiemi di dati che vengono passati dal web server allo script usando un’area di memoria condivisa, un socket TCP/IP od una connessione TCP/IP. Li trovate descritti qui: http://it.wikipedia.org/wiki/Hypertext_Transfer_Protocol . Non è affatto raro che questi “oggetti logici” vengano tradotti dal framework in veri e propri oggetti in senso informatico, cioè in istanze di classi, e che vengano “movimentati” in questa forma all’interno dell’applicazione.

Nei framework più tradizionali, spesso questo elemento del sistema è invisibile perché il web server si limita ad eseguire una copia dell’interprete (PHP, Python, etc.) ed a passargli i dati. Nel mondo Ruby, tuttavia, questo elemento del sistema è spesso chiaramente visibile perché deve essere installato e gestito in modo esplicito e separato. È quello che viene chiamato un “adapter”, come Mongrel. Gli adapter, in realtà, sono spesso dei veri web server ad alte prestazioni che parlano da un lato con un web server “pubblico” (Apache o IIS) che agisce da proxy e dall’altro con l’applicazione web (un programma PHP, Ruby o roba simile).

Front Controller

A questo punto ci vuole qualcosa che riceva la richiesta (GET o POST) dall’utente (dal web server) e provveda ad invocare il giusto programma. In altri termini, ci vuole qualcosa che analizzi la URL (che contiene i parametri della richiesta GET) e che provveda ad invocare lo script che è in grado di rispondere. Questo perché difficilmente un’applicazione web di una certa importanza, come un sito di e-commerce, può essere rappresentata da un singolo script. Più probabilmente, sarà composta da molti piccoli script, ognuno dei quali si occupa di gestire una certa situazione e che risponde ad una diversa URL.

Il programma che si occupa di smistare le chiamate si chiama Front Controller ed è l’implementazione di un ben noto design pattern. O, per essere ancora più precisi, il Front Controller si occupa di invocare un programma, deciso in fase di configurazione del sistema, che si occupa dell’instradamento delle richieste (il “router”) ed un altro che si occupa delle consegne (il “dispatcher”). In molti framework di buona qualità, come Zend, sia il router che il dispatcher possono essere scelti tra un certo numero di possibilità preconfezionate o sostituiti da qualcosa di costruito ad hoc, in modo da garantire la massima flessibilità del sistema. Come si può capire, il Front Controller (insieme ad altri elementi del framework) si occupa della gestione di un complesso flusso di informazioni e di chiamate all’interno dell’applicazione, il cosiddetto “workflow”.

Configuration Manager

I framework hanno l’esigenza di caricare ed eseguire una specifica applicazione (cioè il “sito web” creato dallo sviluppatore). Questa applicazione è composta da vari programmi (file che contengono codice PHP, Python o altro), da varie risorse (immagini, icone, etc.) e da insiemi di dati più o meno complessi (elenchi di CAP, dati presi da database esterni, etc.). Di conseguenza, è chiaro che il framework ha bisogno di sapere dove andare a prendere questa roba e come trattarla. A questo provvede un apposito sistema di gestione della configurazione che può essere basato su file (di solito XML) o su parametri “impliciti” (posizione/esistenza dei singoli file nel file system o cose simili). I sistemi basati su file XML vengono chiamati “configuration-based” perché elencano in modo esplicito i parametri di configurazione. Gli altri sono spesso chiamati “convention-based” perché basano la loro configurazione su una serie di convenzioni formali (vedi: http://it.wikipedia.org/wiki/Convention_Over_Configuration ).

Di solito, un framework NON può cambiare liberamente il suo sistema di gestione della configurazione. Se è nato come configuration-based, al massimo potrà passare da file XML a file di altro tipo, magari .INI, ma non potrà mai gestire una configurazione basata su convenzioni. Si tratta di due architetture difficilmente conciliabili.

I controller, i modelli ed i template

Una volta che il Front Controller è in grado di invocare lo script giusto per rispondere alla richiesta HTTP che proviene dal web server, siamo finalmente arrivati al cuore del sistema. Lo script che viene invocato è infatti un “controller” e fa parte della mitica terna MVC: Model/View/Controller.

Tutti o quasi i moderni web framework vengono descritti come MVC-based. Con questo termine si intende che la generazione della pagina web che viene spedita al browser dell’utente è affidata a tre diversi elementi:

  1. Lo script che viene invocato dal Front Controller, che viene chiamato “controller” a sua volta (giusto per complicare le cose…)
  2. una pagina HTML vuota, che verrà riempita con i materiali forniti dal controller e che viene chiamata “view”. In realtà, la view può essere a sua volta una coppia script/template, ad esempio Python/HTML, ma la sostanza del discorso non cambia.
  3. Se necessario, un ulteriore script che il controller usa per rappresentare il “modello dati” che gli è necessario, il cosiddetto “modello”.

In realtà, questa mitica architettura MVC non la fornisce il framework. Piuttosto, è lo sviluppatore web a sviluppare l’applicazione secondo questa logica. È l’essere umano a scrivere fisicamente il controller (cioè uno script PHP, Python, Java o altro). È l’essere umano a creare la view (template) in HTML. Ed è sempre l’essere umano a creare il modello, se necessario. Di conseguenza, lo sviluppatore può seguire in modo più o meno fedele questo paradigma. Si tratta solo di un metodo utile per non creare dell’inutile confusione nel codice, non di una “legge” che, se non rispettata, può far piantare questo o quel componente del sistema.

Il framework, come tale, si limita a stabilire quale controller chiamare. Il resto è compito dello sviluppatore. Ovviamente, il framework fornisce poi tutta una serie di strumenti utili allo sviluppatore, ad esempio un sistema per agire sulla configurazione dell’applicazione, un sistema per scrivere i file di log, uno per parlare coi database ed uno per gestire gli accessi. Tuttavia, tutto questo non ha nulla a che fare con l’architettura MVC.

Autenticazione ed Autorizzazione

Un altro elemento fondamentale di qualunque applicazione web è la gestione degli accessi. Bisogna identificare l’utente (autenticazione) e stabilire se ha il permesso di accedere a questa o quella risorsa (autorizzazione). A questo provvede abitualmente un framework esterno, come il famoso Spring Security framework di Spring (ex ACEGI security). Trattandosi di un elemento “esterno” ed autonomo, spesso è possibile scegliere di usare questo o quel framework di autenticazione all’interno della stessa applicazione.

In generale, questi framework intercettano la chiamata ad una URL e controllano se l’utente è autenticato (identificato) e se ha i permessi per accedervi (autorizzato). L’intercettazione della chiamata è uno dei meccanismi che deve essere fornito dal framework (dal Front Controller o da un altro dei programmi coinvolti nella gestione del workflow). Di solito viene implementato come meccanismo event/observer o qualcosa di simile.

RDMBS Interface, ORM e OODBMS

Un’altro framework esterno che spesso entra a far parte di un web framework è quello designato a parlare con i database. Qui la scelta si fa veramente molto vasta. I sistemi più antichi, come Zend, utilizzano sostanzialmente una libreria di interfaccia che permette di parlare con vari database SQL in modo abbastanza uniforme (cioè un DAL: Database Abstraction Layer), come Zend_DB. I sistemi più moderni, a torto od a ragione, preferiscono gli ORM (Object/Relational Mapper) come Hibernate.

Francamente, entrambe queste tecniche lasciano abbastanza insoddisfatti nell’uso corrente e questo ha portato recentemente alla nascita di un nuovo movimento, noto come NoSQL, che vede nei sistemi ODBMS una soluzione definitiva.

Template Engines

Una lezione che gli sviluppatori web hanno imparato a loro spese molti anni fa è che non è una buona idea utilizzare del codice (ad esempio PHP) dentro le pagine HTML. Questa pratica porta alla creazione di grovigli di codice del tutto ingestibili e viene quindi evitata da tutti al giorno d’oggi. Da tutti tranne gli sviluppatori PHP e Zend, per essere più precisi (che hanno le loro buone ragioni per insistere in questo brutto vizio).

Al giorno d’oggi, quasi tutti i framework richiedono (e spesso impongono) di usare file separati per ospitare i vari elementi della pagina web che si va a costruire. Di solito, la struttura della pagina viene definita in un apposito “template” rappresentato da una pagina HTML che contiene alcuni marcatori particolari. L’aspetto grafico della pagina (colori, font, etc.) viene definito in un apposito file CSS e la parte dinamica di questo oggetto viene prodotta da un apposito file PHP, Python, Java o altro, il cosiddetto controller.

Quasi tutti i framework permettono di scegliere liberamente quale sistema usare per gestire i template HTML, ad esempio tra Cheetah e Mako per Python e tra FreeMarker e Apache Velocity in Java. Questi “template engine”, infatti, sono quasi sempre elementi esterni al framework e del tutto autonomi.

Logging

Un altro framework che normalmente vive di vita autonoma rispetto al web framework principale è quello che si occupa del logging, cioè della registrazione delle attività. Più esattamente, di solito si tratta di un modulo esterno, spesso appartenente alle librerie di base del linguaggio, e non di un vero e proprio framework.

Code Generators

Molti framework, tra cui Zend e Pylons, fanno uso di appositi script per generare lo scheletro di un’applicazione. Alcuni, come Django e Ruby-on-Rails, fanno uso di generatori di codice e/o di tecniche di metaprogrammazione anche per creare delle interfacce utente pronte all’uso con cui gestire il database (“scaffolding”) e per altri scopi. L’uso di questi generatori di codice è abbastanza frequente nei web framework veri e propri ed in quei sistemi che io chiamo “generatori di applicazioni”, come, appunto, Django e Ruby-on-Rails.

Project Management Systems

Il passo successivo, rispetto ai generatori di codice sono i sistemi come Apache Maven (Java) che si occupano sia della creazione dello scheletro dell’applicazione che della gestione successiva dell’intero progetto e del suo dispiegamento (“deployment”) sul server. Java, Python e Ruby hanno degli strumenti molto raffinati per questo scopo.

Dal toolkit al framework: scheletri di applicazioni

Ora che abbiamo un’idea di quali siano i componenti abituali di un framework, possiamo capire come si passa da un semplice toolkit (toolbox) ad un vero framework.

Quasi tutti gli elementi che ho appena descritto sono disponibili come librerie separate, che lo sviluppatore può scegliere di utilizzare o meno. Nel mondo Java, questi elementi sono quasi sempre separati tra loro e chiaramente distinguibili l’uno dall’altro. Esistono librerie per gestire l’accesso ai database, framework ORM come Hibernate, framework di sicurezza come ACEGI e altre diavolerie che lo sviluppatore può adottare individualmente e mescolare con altre come preferisce. Finché la situazione resta questa, siamo di fronte ad un toolkit e nulla più.

Se però passiamo ad un sistema che utilizza un Front Controller per effettuare il routing ed il dispatching delle richieste e per gestire il workflow dell’applicazione, siamo già di fronte a qualcosa di molto più complesso. Soprattutto, siamo di fronte ad un sistema che impone dei vincoli allo sviluppatore, cioè siamo di fronte ad un vero framework.

In realtà, i framework quasi sempre si spingono ancora oltre e definiscono uno scheletro di applicazione di base che lo sviluppatore deve rispettare. Questo perché il framework deve sapere dove andare a pescare le cose che gli occorrono e deve essere sicuro che certi elementi siano presenti.

Di conseguenza, può essere utile pensare ad un framework come ad una applicazione di base che fornisce gli strumenti necessari per lo sviluppo e che impone alcuni vincoli.

Dal framework al generatore di applicazioni

Questi scheletri di applicazione sono spesso generati da un apposito script (nel mondo Java si usa l’onnipotente Maven, per esempio). Ovviamente, una volta adottata questa tecnica per creare lo scheletro dell’applicazione (e magari anche per gestire il progetto nel seguito), viene d’istinto di usarla anche per generare altri elementi dell’applicazione, come l’interfaccia verso i database (“scaffolding”).

Questa linea evolutiva ha portato alla creazione di sistemi come Ruby-on-Rails e Django che possono essere considerati dei veri generatori di applicazioni o persino degli strumenti di sviluppo visuali. Questi sistemi, infatti, si affidano ad appositi script e/o a tecniche di metaprogrammazione per creare e gestire gran parte dell’applicazione.

Dal framework al CMS: più funzioni e gestione della configurazione

Continuando a parlare in termini evolutivi, possiamo vedere come un CMS (Content Management System) sia una naturale evoluzione di un framework. Un CMS, infatti, è sostanzialmente uno “scheletro di applicazione” più complesso e più completo di quello che caratterizza molti framework.

In particolare, un CMS di solito deve fornire le funzionalità necessarie per riconoscere, caricare e configurare dei moduli aggiuntivi. Molti CMS sono infatti costruiti proprio come collezione organizzata di moduli. Questo vuol dire che il CMS deve fornire uno schema all’interno del quale inserire i moduli ed un sistema di configurazione con cui renderli attivi e configurarli.

Oltre a questo, un CMS deve fornire un’implementazione reale e funzionante di alcuni servizi che nei framework sono presenti solo come servizi potenziali. Questo è il caso del sistema di autenticazione, per esempio, che deve essere dotato delle pagine di login e di gestione del profilo utente (cambio password e azioni simili).

Dal CMS allo Shopping Center: i soldi in gioco

Il passaggio successivo, cioè quello dal CMS ad un classico “shopping center” come Amazon.com, è rappresentato dal fatto che il sistema e lo sviluppatore devono farsi carico della gestione di alcune importanti realtà del mondo fisico: i soldi ed i prodotti. Si tratta quindi di trattare i rapporti con le banche ed il relativo sistema di gestione dei pagamenti, così come il rapporto con il magazzino ed i corrieri, con la conseguente gestione delle spedizioni.

Dal punto di vista tecnico, la vera differenza consiste nella necessità di registrare (log) tutte le operazioni e, per quanto possibile, renderle reversibili (annullabili). La maggior parte del lavoro ha luogo quindi sul sistema di amministrazione dell’applicazione e nell’interfaccia con il database.

Conclusioni

Non so se ho risposto in maniera esauriente al mio collega e se ho soddisfatto le vostre curiosità. Comunque, se avete domande da fare o qualcosa da dire, potete usare il sistema dei commenti qui sotto.

Alessandro Bottoni

L’immagine proviene da qui:

sottosuolo.net/-site-/fotografia_scheda.asp?ID=2553

ed è una formidabile interpretazione della figura dello Scarpantibus creata da Ferdinando Segreti. Per quanto sono riuscito a capire, l’immagine è liberamente utilizzabile.

Comments
One Response to “L’ambarasgnao”
  1. yanfry scrive:

    Ciao Alessandro ti disturbo da qui per chiederti se hai ricevuto la mia mail dall’account gmail e se hai tempo per darci una risposta, scusa ancora, Gianfranco.

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: