Mentre la bufera di neve torna ad affliggere Bologna, io giochicchio con Mojolicious e mi segno un paio di note.
Per provare a scimmiottare un’interfaccia REST seria, m’ero costruito a colpi di given un controller che generava la risposta in funzione dell’attributo format dello stash (solite cose: html, json, xml); per altro, poichè non stavo usando “the right way” mi stavo pure scontrando con alcune difficoltà implementative (1).
In realtà esiste un comodissimo metodo respond_to che già compie questa selezione internamente (il codice).
Dato questo codice:
use Mojolicious::Lite;
get ‘/test’ => sub {
my $self = shift;
my $data = { a => 1, b => 2, c => 3 };
$self->respond_to(
json => { json => $data },
html => { text => $self->dumper($data) }
);
};
app->start;
possiamo ottenere diverse risposte:
GET /test HTTP/1.1
User-Agent: Mojolicious (Perl)
Accept: text/html
Content-Length: 0
Host: localhost:3001
HTTP/1.1 200 OK
X-Powered-By: Mojolicious (Perl)
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
Date: Sat, 04 Feb 2012 15:33:23 GMT
Server: Mojolicious (Perl)
Content-Length: 39
{
‘c’ => 3,
‘a’ => 1,
‘b’ => 2
}
—————————–
(2) sim@titanio:/tmp$ mojo get -v -H ‘Accept: application/json’ ‘http://localhost:3001/test’
GET /test HTTP/1.1
User-Agent: Mojolicious (Perl)
Accept: application/json
Content-Length: 0
Host: localhost:3001
HTTP/1.1 200 OK
X-Powered-By: Mojolicious (Perl)
Content-Type: application/json
Connection: keep-alive
Date: Sat, 04 Feb 2012 15:34:01 GMT
Server: Mojolicious (Perl)
Content-Length: 19
{"c":3,"a":1,"b":2}
—————————
(3) sim@titanio:/tmp$ mojo get -v -H ‘Accept: text/plain’ ‘http://localhost:3001/test’GET /test HTTP/1.1
User-Agent: Mojolicious (Perl)
Accept: text/plain
Content-Length: 0
Host: localhost:3001
HTTP/1.1 204 No Content
X-Powered-By: Mojolicious (Perl)
Connection: keep-alive
Date: Sat, 04 Feb 2012 15:34:40 GMT
Server: Mojolicious (Perl)
Content-Length: 0
————————–
(4) sim@titanio:/tmp$ mojo get -v -H ‘Accept: text/plainz’ ‘http://localhost:3001/test’
GET /test HTTP/1.1
User-Agent: Mojolicious (Perl)
Accept: text/plainz
Content-Length: 0
Host: localhost:3001
HTTP/1.1 200 OK
X-Powered-By: Mojolicious (Perl)
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
Date: Sat, 04 Feb 2012 15:35:15 GMT
Server: Mojolicious (Perl)
Content-Length: 39
{
‘c’ => 3,
‘a’ => 1,
‘b’ => 2
}
Le prime tre sono corrette, poichè dati determinati header ottengo le risposte giuste:
- text/html – 200
- application/json – 200
- text/plain – 204 – nessuna rappresentazione corretta
Il quarto a mio avviso è un fail, o meglio una scelta discutibile: invece che riconoscere l’header sbagliato e mandare a spendere il client con un 204, gli serviamo html.
Benchè alla fine di quel metodo venga restituito un 204 se il $target non esite (#L423), il gioco “sporco” accade 20 righe prima dove nel caso la rappresentazione passata non venga individuata, si ricade nella situazione di default (html di solito). Il problema a questo punto si incrocia con la possibilità che Mojolicious non abbia dentro di se la rappresentazione corretta benchè sia comune (openoffice, pdf – che forse ora sono stati inseriti, non so), cosa che può portare a conclusioni di default anche quando la rappresentazione richiesta è corretta ma non presente nei tipi di Mojo. In ogni caso, si può sempre aggiungere qualcosa ai MIME.
Ho comunque poi scoperto che la cosa è stata discussa in passato ed è stato deciso così.
Well, basta saperlo.
PS: Io avrei lasciato i client mal fatti nel loro brodo, ma tant’è – probabilmente non capisco bene le implicazioni.
Note:
(1) Le rotte in Mojolicious permettono di selezionare il formato utilizzando un array reference
/formats GET formats ^/formats\.(xml|html)$
ma, come si vede dalla regex, questo fa sì che la rotta “pulita” diventi “/formats.” che non è proprio quello che si vuole, di solito.
Da un po’ di tempo a questa parte tutti i web framework presentano riferimenti all’architettura REST che propone di sfruttare completamente (?) le potenzialità del protocollo HTTP senza livelli aggiuntivi (ie SOAP).
- Domande e risposte su stackoverflow
- Steve Klabnik: e Haters gonna HATEOAS
- Dr. Elkstein: What is REST?
- R. T. Fielding: REST APIs must be hypertext-driven
Poi, se proprio vogliamo farci del male… Architectural Styles and the Design of Network-based Software Architectures di Roy T. Fielding.
Ho rispolverato alcuni appunti cartacei relativi i Ruoli di Perl Moose che riporto qui.
- I ruoli rappresentano comportamenti condivisi fra le classi
- La classe fa ciò che dice il ruolo.
- I ruoli non sono classi; infatti i ruoli non si ereditano e non si istanziano.
- I ruoli vengono consumati da classi o da altri ruoli.
- I ruoli sono composti in una classe con la funzione with.
- Tutti i metodi, modificatori, attributi definiti in un ruolo sono aggiunti direttamente alla classe che consuma il ruolo.
- Attributi e metodi appariranno come se fossero definiti nella classe.
- Una sottoclasse della classe consumata (cioè con il ruolo) eredita tutti questi metodi/attributi.
Riferimenti:
- Moose::Role
- Moose::Manual::Roles
LaTeX è un linguaggio di markup basato sul TeX – un programma di tipografia digitale progettato da Donald Knuth.
I pacchetti relativi tex minimi su Debian sono i seguenti (discendono dall’installazione di texlive-base, e dipendono dalla distribuzione textlive):
- libkpathsea5
- luatex
- tex-common
- Pacchetto con file in comune e documentazione generica su TeX e Debian
- texlive-common
- texlive-doc-base
- Documentazione TeX Live
- texlive-binaries
- texlive-base
Pacchetti necessari per usare LaTeX.
Pacchetti aggiuntivi.
- preview-latex-style
- texlive-pictures
- texlive-latex-extra
Ho trovato interessante il tabellone linkato perchè almeno può dare una direzione da seguire per colmare quel che manca.

Smanettando con Mojolicious, mi sono ritrovato a guardare meglio il protocollo http (rfc 2616), che in effetti ho sempre usato ma approfondito poco.
Un po’ di info estese si possono trovare su wikipedia, ma in sostanza HTTP è un protocollo che si basa su richieste di uno user agent (client) e risposte di un web server (server).
Generalmente ad una richiesta del client segue una risposta del server che può fornire risorse di qualunque genere, anche se generalmente server file HTML – interpretati poi dal client; un messaggio di risposta contiene informazioni sullo stato (attraverso un codice numerico), vari header, e eventualmente un contenuto.
Le risorse HTTP sono identificate da URI (Uniform Resource Identifiers) o, più precisamente, URL (Uniform Resource Locators) che ne permettono la chiamata.
La principale differenza fra la versione del protocollo 1.0 e la 1.1 è che la specifica più recente permette di riutilizzare la medesima connessione più volte – mentre la versione più antica richiedeva una connessione separata per ogni transazione richiesta-risposta.
Richiesta
Un messaggio di richiesta può presentarsi come segue:
GET /get/20120105_002516.jpg HTTP/1.1
User-Agent: Mojolicious (Perl)
Content-Length: 0
Host: localhost:19987
La richiesta presenta un metodo, un URI e un protocollo, alcuni header aggiuntivi, e la linea “Host:” che determina a chi stiamo chiedendo la risorsa (obbligatorio nella v. 1.1).
Risposta
La risposta del server alla nostra richiesta è la parte interessante. In cima c’è lo status della risposta, seguito da una serie di header che possono fornire informazioni aggiuntive di vario genere; infine, dopo una riga vuota, segue il corpo.
X-Powered-By: Mojolicious (Perl)
Connection: keep-alive
Date: Thu, 05 Jan 2012 22:57:04 GMT
Server: Mojolicious (Perl)
Content-Length: 22880
Un body se presente mandato via HTTP request o response è in un formato codificato definito dagli header.
Quando un corpo (entity-body indica l’insieme di oggetti serviti come corpo – compresa ad esempio una codifica di sicurezza) è incluso in un messaggio, il tipo del body è determinato via Content-Type e Content-Encoding.
Il Content-Type specifica il tipo di media e l’Encoding può essere usato per, ad esempio, compressioni applicate ai dati; non vi è alcun Content-Encoding di default.
Qualunque messaggio HTTP/1.1 contenga un body dovrebbe includere un Content-Type: in caso di mancanza, il client può provare a capire cosa gli viene mandato; se l’ispezione non ha successo, il ricevente dovrebbe trattare il file come “application/octet-stream”.
Anche il Content-Length è molto importante perchè fornisce informazioni sul numero di byte passati.
Volevo vedere questa gamma di caratteri nei browser su titanio, e ho dunque installato i pacchetti debian
- ttf-wqy-microhei
- ttf-wqy-zenhei
- xfonts-wqy
It works!