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:

#!/usr/bin/env perl
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:

(1) sim@titanio:/tmp$ mojo get -v -H ‘Accept: text/html’ ‘http://localhost:3001/test’
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:

  1. text/html – 200
  2. application/json – 200
  3. 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

get ‘/formats’ => [format => [‘html’,‘xml’]] => sub { };
sim@titanio:/tmp$ perl myapp.pl routes -v
/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).

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.
package Breakable;
use Moose::Role;

has ‘is_broken’ => (
      is  => ‘rw’,
      isa => ‘Bool’,
);

sub break {
      my $self = shift;
      print "I broke\n";
      $self->is_broken(1);
}

package Car;
use Moose;
with ‘Breakable’;

has ‘engine’ => (
      is  => ‘ro’,
      isa => ‘Engine’,
);

my $car = Car->new( engine => Engine->new );
print $car->is_broken ? ‘Busted’ : ‘Still working’;   # Still working
$car->break;                                          # I broke
print $car->is_broken ? ‘Busted’ : ‘Still working’;   # Busted
$car->does(‘Breakable’)

Riferimenti:

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.

texlive-latex-base
texlive-latex-recommended

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. :)

grafici

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:

sim@titanio:~/dev/perl/homerun$ ./homerun.pl get –verbose ‘/get/20120105_002516.jpg’ 2>&1| cat | head -n13
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.

HTTP/1.1 200 OK
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!

« Previous Articles    
SIMOTRONE WEB PAGE is based on WordPress platform, RSS tech , RSS comments design by Gx3.