Redvex3
Benvenuto visitatore
Login Registrati
Spinner
The Rails Way... The REST Way

Alla scoperta del mondo delle applicazioni RESTful.

Approfittando del fatto di dover imparare le novità di rails 2.0 (e 2.1) ho pensato di concentrarmi 10 minuti sulle applicazioni RESTful, di fatto una delle caratteristiche più appetitose di Rails e su cui fin'ora non avevo indagato più di tanto.

Ma cosa vuol dire REST?

Per la precisione vuol dire Representational state transfer, ovvero un'architettura software basata sul concetto fondamentale di risorsa e implementa il protocollo HTTP nella sua interezza.

Chiunque abbia una minima conoscenza di html conosce i metodi GET e POST, sicuramente avrete creato un form inviato via post o digitato un url nella barra indirizzi inviando una richiesta via get. Ma il protocollo HTTP ha ulteriori due metodi: PUT e DELETE.

Il primo serve a modificare una risorsa, la seconda per cancellarla. In realtà i browser non implementano questi metodi e Rails sopperisce a questa mancanza gestendo i metodi PUT e DELETE simulandone il comportamento via POST.

A cosa ci serve tutto questo? Il principio è semplice: ogni risorsa è identificata univocamente da un indirizzo, le operazioni da fare su di essa vengono identificate dai metodi con cui sono chiamate.

Per capire meglio il meccanismo generiamo tramite scaffold una piccola applicazione REST che gestisca una tabella con solo 2 campi, per esempio titolo e descrizione di un progetto.

Creiamo l'applicazione RESTbook

rails RESTbook

Se avete la versione 1.2.6 potete usare lo scaffold_resource

script/generate scaffold_resource project name:string desc:text 

Con la versione 2.0 di rails lo scaffold è stato sostituito con lo scaffold_resource, quindi non rimane che lanciare lo scaffold:

script/generate scaffold project name:string desc:text 

Se usate sqlite lanciate direttamente la migration, se usate mysql create prima il db.

Diamo un'occhiata al file routes.rb dove troviamo la prima novità:

map.resources :projects

Ovvero Rails ha mappato il nostro progetto come risorsa.

i Rest URL

Come sappiamo le routes incidono fortemente sugli url della nostra applicazione, in un'applicazione RESTful gli url non seguono più il modello /:controller/:action/:id, ma quello più semplice /:resource/:id, ogni azione che si riferisce a questa risorsa sarà richiamata tramite lo stesso url. Come fa il controller a "capire" quale azione intraprendere? Usando i metodi del protocollo HTTP:

Metodi HTTP e azioni RESTful
Metodo-REST REST-URL  Metodo URL 
GET /projects/1  GET  /projects/show/1
DELETE /projects/1  GET  /projects/destroy/1
PUT /projects/1  POST  /projects/update/1
POST /projects  POST  /projects/create

Il tutto sembra abbastanza complicato, ma in realtà non lo è.

Se nella barra degli indirzzo digito /projects/1 vuol dire che voglio vedere il progetto con id uguale ad 1. Se chiamo il DELETE sulla risorsa progetto con id=1 vuol dire che la voglio cancellare. Se mando un form tramite PUT vuol dire che voglio "mettere" i dati inseriti nella risorsa 1, ovvero voglio modificare e infine inviando un form via POST vuol dire che voglio postare un progetto, ovvero inserire.

i Controller REST

Una volta capito come funzionano gli URL diamo un'occhiata al controller.

Il codice dell'azione show è il seguente:

# GET /projects/1 
# GET /projects/1.xml
def show
@project = Project.find(params[:id])
respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => @project.to_xml }
end
end

Rispetto ad un controller classico troviamo una fondamentale differenza, ovvero la direttiva "respond_to". Questo meccanismo diventato di default in rails 2.0 e successivi serve a rispondere in maniera opportuna alle richieste effettuate. In questo esempio l'applicazione rispondere in html ad una richiesta html e in xml ad una richiesta in xml.

Volendo possiamo estendere questo comportamento per risponde ad altri formati come rss, atom e persino iphone.

Le view REST

I metodi redirect_to e link_to non sono adatti alle applicazioni rest in quanto prendono come parametri gli url classici controller/action/id. Dobbiamo quindi seguire una piccola convenzione richiamando degli helper autogenerati. In particolare:

Standard path helper
       
projects_path /projects GET index
project_path(:id) /projects/1 GET show
new_project_path /projects/new GET new
edit_project_path(:id) /projects/1/edit GET edit
projects_path /projects POST create
project_path(:id) /projects/1 PUT update
project_path(:id) /projects/1 DELETE destroy

New, Edit e Destroy

A prima vista le prime due azioni rompono il paradigma rest, ma l'impressione sparisce quando si considera che le azioni che presentano i form per inserire o modificare sono solo azioni preparatorie e che non fanno parte delle operazioni CRUD

Osserviamo ora i form per new ed edit.

New

form_for(:project, :url => projects_path) do |f| ... 
=>
<form action="/projects" method="post">

Edit

form_for(:project, :url => project_path(@project), 
:html => { :method => :put }) do |f| ...
=>
<form action="/projects/1" method="post">
<div style="margin:0;padding:0">
<input name="_method" type="hidden" value="put" />
</div>

Come sappiamo l'html supporta nativamente il metodo post, ma non il put. Rails simula il comportamento di PUT inserendo una input hidden chiamato _method con valore put e passa il tutto via post.

Destroy

Discorso analogo vale per DELETE. Anche in questo caso l'html non supporta nativamente questo metodo e rails risolve in maniera analoga:

link_to "Destroy", project_path(project), :method => :delete 
=>
<a href="/projects/1"
onclick="var f = document.createElement(’form’);
f.style.display = ’none’; this.parentNode.appendChild(f);
f.method = ’POST’; f.action = this.href;
var m = document.createElement(’input’);
m.setAttribute(’type’, ’hidden’);
m.setAttribute(’name’, ’_method’);
m.setAttribute(’value’, ’delete’); f.appendChild(m);f.submit();
return false;">Destroy</a>

Conclusioni

In questo primo articolo su Rest ho cercato di dare una panoramica su questa metodologia di programmazione, c'è ancora tanto da dire, per esempio sulle risorse annidate, sui metodi "custom" e così via... mi riprometto di continuare il discorso nei prossimi articoli.

Back
se non sei registrato, registrati per inserire commenti, oppure effettua il login

 
Notizie Mac
 
 
1
PdC Calculator
1 2 3
 
View Gianni Mazza's profile on LinkedIn