Una REST API che adatta le sue risposte al MIME Media-Type delle richieste HTTP

Da qualche tempo sto lavorando alla implementazione di una REST API. In linea generale e semplificando, una API è un servizio che espone alcune funzionalità, è accessibile via internet più o meno liberamente ed è, infine, utilizzabile non solo da persone fisiche ma anche e soprattutto da altre applicazioni. Un esempio di API è quella di Facebook, che consente a chiunque di creare applicazioni che interagiscono con gli utenti e le pagine Facebook. Già, se non ci fosse la API non esisterebbero i terribili giochini Facebook…

Una delle specifiche REST più importanti vuole che un servizio RESTful sia in grado di fornire dati in più formati, in modo tale da soddisfare il maggior numero possibile di utenti/applicazioni. Immaginiamo un servizio che fornisce i risultati delle partite del campionato di calcio. Supponiamo che arrivino tre richieste successive per lo stesso risultato: la prima potrebbe chiedere una risposta in formato XML, la seconda in JSON e la terza in HTML. Il  nostro servizio deve rispondere a tutte e tre le richieste, adattando il flusso di dati della risposta al formato di ognuna.

FlaskNel mio caso la API che sto implementando supporta XML, JSON, HTML e testo puro. E’ scritta in Python (ma va!) e si appoggia all’eccellente Flask micro web framework. Per risolvere in maniera elegante il problema delle risposte multi-formato ho deciso di usare i decorator, una delle caratteristiche più interessanti di Python. Dopo un po’ di lavoro in proprio ho scoperto che qualcuno aveva già risolto il problema, per giunta con la stessa tecnica. MimeRender di Martin Blech è un’ottima soluzione, solo che è specifica per web.py (un altro web framework). La mia soluzione non disponeva di alcune opzioni interessanti che MimeRender include; ho deciso allora di scrivere un port di MimeRender per Flask, e di metterlo a disposizione del pubblico.

Istruzioni per l’uso

Prima di tutto è necessario fornire le funzioni da usare per il rendering, una per ogni formato che intendiamo supportare:

Quindi decoriamo la nostra funzione, definendo per lei la mappa delle funzioni di rendering:

Tutto qui! In caso di richiesta GET la funzione index restituisce un dizionario, il quale verrà reso da MimeRender come XML, JSON o quant’altro, a seconda del Content-Type specificato nella richiesta HTTP:

Su github trovate l’esempio completo nonché il codice sorgente del renderer, che potete scaricare liberamente.