Banner

Restfulie

Essa semana eu resolvi dar uma olhada no plugin Restfulie da Caelum. Depois de ter tentado seguir o tutorial deles do github e não ter dado certo (já que algumas informações estavam faltando), resolvi ler o código do plugin e notei que é muito mais simples do que eu imaginava.

A função do plugin e o porque ele é legal, você pode ler no github mesmo. Aqui só vou mostrar o que eu fiz para realmente entender como a coisa funciona. =]

Acho que a parte mais difícil de um tutorial é criar um exemplo que não seja totalmente imbecil. Não consegui... então vai esse mesmo.

O que eu vou fazer é criar um resource bem “simplão” que simula a instalação de alguma coisa em algum lugar. Tudo o que o meu resource tem é um nome, um servidor e um status. Status. Palavrinha importantíssima que tem que ter, afinal é ela que armazena o estado em que se encontra o seu resource.

Ah, um PS aqui. Vou fazer só o server side. Client side fica pra outra hora.

No caso aqui, o que acontece é o seguinte: Fulaninho vai lá, cria um resource que fica pendente a espera da boa vontade de alguém de instalá-lo. Enquanto pendente, este resource pode também ser cancelado antes da instalação.

Uma vez instalado, este resource pode ser somente suspenso e depois de suspenso ele pode ser ou reativado ou deletado.

Abaixo uma representação dos estados e das transições:

 

Estados:
I. Pendente
II. Cancelado
III. Ativo
IV.Suspenso
V. Deletado

Transições:
1.Cancelar
2.Instalar
3.Suspender
4.Reativar
5.Deletar

Bom, então vamos lá.

Primeiro, criar o projeto e o recurso:

 
rails DB
 ./script/generate scaffold resource nome:string servidor:string status:string 
 rake db:migrate 


Depois instalar o plugin:
 
 script/plugin install git://github.com/caelum/restfulie.git


Se você criar um resource agora e olhar o xml, vai aparecer daquele jeito feio ainda.

Para que o plugin realmente faça o que se propõe é necessário explicitar no controlador a função “to_xml” no método show. O que o plugin faz é sobrescrever este método.

No meu caso, o resources_controller.rb ficou assim:

 
 # GET /resources/1 
 # GET /resources/1.xml 
 def show 
 @resource = Resource.find(params[:id]) 
 
 respond_to do |format| 
 format.html # show.html.erb 
 format.xml  { render :xml => @resource.to_xml(:controller => self, :except => [:created_at, :id, :updated_at]) }
 end 
 end


Mas a mágica do plugin fica no model resource.rb onde deve ser definido o método following_transitions:

 
 def following_transitions 
 transitions = [] 
 transitions << [:show, {}] 
 transitions 
 end


Nesse método serão definidas as transições para cada estado:

 
def following_transitions 
 transitions = [] 
 transitions << [:instalar, {:id => id}] if is_pending? 
 transitions << [:cancelar, {:id => id}] if is_pending? 
 transitions << [:suspender, {:id => id}] if is_installed? 
 transitions << [:reativar, {:action => :instalar, :id => id}] if is_suspended? 
 transitions << [:deletar, {:id => id}] if is_suspended? 
 transitions 
 end

Isso quer dizer que se estiver pendente, o recurso poderá ser cancelado ou instalado, se estiver suspenso, poderá reativado, e por ai vai.

Essas funções “is_pending?”, etc eu criei como forma de controlar as transições. Uma delas ficou assim:

 
def is_pending? 
 status == "pending" 
 end

Bem simples.

Final:

<resource>
<nome>Nome02</nome>
<servidor>Servidor02</servidor>
<status>pending</status>
<atom:link rel="instalar" href="http://localhost:3001/resources/instalar/2"/>
<atom:link rel="cancelar" href="http://localhost:3001/resources/cancelar/2"/>
</resource>

 
To Follow or not
del.icio.us: nurdagniriel Facebook: nurdagniriel Flickr: nurdagniriel LastFM: nurdagniriel MySpace: nurdagniriel Orkut: 6524402225602248237 Picasa: jmourisca Google Reader: 12928185900518312672 Twitter: nurdagnen YouTube: nurdagniriel
News
www.wacken.com: Latest News about W:O:A
Latest News about W:O:A
Who's Online
We have 2 guests online
Rails Summit 2009

Rails Summit 2009