YQL! Parte 3: Usando tabelas do YQL! em uma aplicação Ruby e Java com Restfulie

Nos dois posts anteriores foi explicado como desenvolver as tabelas do YQL!, inclusive escrevendo o código Javascript para tabelas que envolviam uma lógica mais complexa. Nesse post eu vou mostrar como é possível utilizar uma tabela já criada (usando como exemplo a tabela criada no post anterior) tanto em uma aplicação Ruby quanto em uma aplicação Java utilizando o Restfulie para acessar.

O que é o Restfulie?

O Restfulie é uma biblioteca que permite acessar serviços REST através de uma interface agradável. Além disso, os serviços REST podem possuir hypermedia em suas respostas e através da biblioteca é possível navegar sobre os links através da própria API.

Em Ruby com uma aplicação Rails

Considerando que você esteja utilizando RVM (e se não estiver, já está na hora) e com o Rails 3 configurado, adicione a gem do Restfulie ao seu Gemfile:

gem 'restfulie'

Em seguida, crie um novo controller para conseguirmos fazer uma tela para visualizar os resultados:

rails g controller cursos

No seu controller, adicione um método novo que fará a ação de buscar as informações da tabela do YQL! e disponibilizar essas informações para a View:

def index
  #vamos adicionar codigo aqui
end

No método index vamos declarar duas variáveis, uma para guardar a url do YQL! e outra para armazenar a query que vamos executar. Com isso teremos:

def index
  base_url = "http://query.yahooapis.com/v1/public/yql"
  query = "use 'http://ahalmeida.me/tabelas_yql/caelum.proximoscursos.xml'; select * from caelum.proximoscursos;"
  #vamos fazer a consulta aqui
end

O próximo passo é executarmos a consulta com o Restfulie. Para isso, basta adicionarmos o seguinte código:

Restfulie.at(base_url).get(:q => query)

O que o código acima faz é uma requisição get para a base_url passando um parâmetro q cujo valor é a query que desejamos executar. Podemos pegar a resposta desse método get e guardarmos em uma variável. Essa variável guardará uma estrutura de hashes que representa a mesma estrutura do XML devolvido pelo serviço. No caso, o XML devolvido pelo YQL! é algo similar com:

<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng"
    yahoo:count="1" yahoo:created="2010-10-19T12:51:13Z" yahoo:lang="en-US">
    <results>
        <cursos>
            <curso>
                <nome>FJ-26:
Laborat&oacute;rio Web com JSF2 e CDI</nome>
                <data>23/10 a 27/11</data>
                <periodo>S&aacute;bado (9:00 as 17:00)</periodo>
                <cidade>Rio de Janeiro</cidade>
                <comentario/>
            </curso>
            <!-- outros cursos aqui ... -->
        </cursos>
    </results>
</query>

Com isso o código para conseguirmos buscar todos os cursos com o Restfulie dessa estrutura de XML da resposta é:

resp = Restfulie.at(base_url).get(:q => query)
@cursos = resp['query']['results']['cursos']['curso']

Dessa forma a classe CursosController ficaria:

class CursosController < ApplicationController   
  def index
    base_url = "http://query.yahooapis.com/v1/public/yql"
    query = "use 'http://ahalmeida.me/tabelas_yql/caelum.proximoscursos.xml'; select * from caelum.proximoscursos;"  
    resp = Restfulie.at(base_url).get(:q => query)
    @cursos = resp['query']['results']['cursos']['curso']
  end
end

A variável cursos disponibilizada para a view é um Array contendo objetos que possuem as informações dos cursos devolvidas pelo YQL!. Para finalizar podemos criar uma view para o index do Controller que acabamos de fazer e mostrar as informações dos cursos:

<% @cursos.each do |c| %>
  <%= c.nome %>
  <%= c.periodo %>
<% end %>

Em Java

O processo em Java é similar. Através do Restfulie que está disponível em http://github.com/caelum/restfulie-java você consegue também consumir serviços REST, no entanto é necessário escrever um pouco mais de código do que na versão Ruby, por características da linguagem.

De qualquer maneira, uma vez que tenha baixado o Restfulie e configurado em seu projeto, vai ser necessário representar através de classes a estrutura do XML que será devolvido. No caso da query de cursos da Caelum teremos as seguintes classes:

@XStreamAlias("query")
public class Query {
    private Results results;
}

@XStreamAlias("results")
public class Results {
    private	Cursos cursos;
}

@XStreamAlias("cursos")
public class Cursos {
    @XStreamImplicit(itemFieldName="curso")
    private List cursos;
}

@XStreamAlias("curso")
public class Curso {
    private String nome;
    private String data;
    private String periodo;
    private String cidade;
    private String comentario;
}

Em seguida podemos criar uma instância do Restfulie e registrar os tipos que desejamos receber:

RestClient client = Restfulie.custom();
client.getMediaTypes().register(new XmlMediaType().withTypes(Query.class));

O próximo passo é executarmos a requisição e pegarmos o objeto que representa o XML e percorrermos todos os cursos:

Response response = client.at("http://query.yahooapis.com/v1/public/yql?q=use%20'http%3A%2F%2Fahalmeida.me%2Ftabelas_yql%2Fcaelum.proximoscursos.xml'%3B%20select%20*%20from%20caelum.proximoscursos%3B").accept("text/xml;charset=utf-8").get();

Query q = response.getResource();

for (Curso c : q.getResults().getCursos().getCursos()) {
    System.out.println(c.getNome());
}

Logicamente, esse código pode ser reaproveitado em qualquer tipo de aplicação (seja web ou Desktop).

Conclusão

Para utilizar uma tabela criada basta consumir essa tabela através de uma API que envie requisições HTTP. O ideal é que ela também torne agradável trabalhar com a resposta. Nesse caso utilizei o Restfulie, mas poderia ter sido também qualquer outra biblioteca, como o HTTParty.

Usando melhor o RVM: trabalhando com gemsets

O RVM (Ruby Version Manager) é uma ferramenta que permite que se trabalhe com diferentes versões de Ruby numa mesma máquina de forma simples.

A ideia desse post não é falar sobre como configurar o RVM do zero. Caso esteja interessado nisso, dê uma lida no post do Fabio Akita.

Uma das coisas mais comuns em tempos de Rails 3 é possuirmos aplicações já feitas em Rails 2, e enquanto isso queremos desenvolver em Rails 3. A solução para trabalharmos de forma simples e organizada com gems de versões diferentes dentro de uma mesma versão de ruby é usando as gemsets do RVM.

Uma gemset, como o próprio nome diz, é um conjunto de gems, no qual você atribui um nome para elas, e consegue alternar entre os mesmos facilmente. Dessa forma, podemos alternar entre diferentes versões de gems executando um simples comando no shell. Isso é útil para testarmos compatibilidades entre os nosso código e as versões das gems que ele utiliza.

O primeiro passo para criar uma gemset, considerando que o RVM já esteja instalado é: rvm gemset create nome_da_gemset. Com isso, uma nova gemset é criada com o nome definido. Agora que já temos a gemset criada, podemos utilizá-la com o comando rvm gemset use nome_da_gemset. É possível também trocar para uma gemset específica de uma versão definindo a RVM que se quer utilizar junto da gemset: rvm use 1.9.1@nome_da_gemset.

Para instalar gems dentro dessa versão, basta utilizar gem install nome_da_gem (sem o sudo).

Por padrão, as instalações do ruby dentro do RVM já possuem uma gemset. Para voltar para ela, basta acessar diretamente a sua rvm com rvm use 1.9.1, por exemplo.

Mas, nesse monte de gemsets, como posso saber em qual eu estou e quais eu tenho disponíveis para utilizar? Para o primeiro, existe o comando rvm gemset name.

É possível alterar o script do seu .bash_profile para mostrar o nome da gemset em que você está também, basta adicionar ao script que o próprio RVM sugere, o seguinte comando: (`rvm gemset name`), com isso, ele ficará da seguinte forma:

export PS1='\w `~/.rvm/bin/rvm-prompt i v` (`rvm gemset name`) `git branch 2> /dev/null | grep -e ^* | sed -E s/^\\\\\*\ \(.+\)$/\(\\\\\1\)\ /`\[33[37m\]$\[33[00m\] '

Para listar as gemsets disponíveis, basta executar rvm gemset list e caso não precisa mais de uma gemset, basta executar rvm gemset delete nome_da_gemset.

Por fim, uma outra funcionalidade bastante útil é a criação de arquivos .rvmrc. Esses arquivos funcionam como um script de inicialização da rvm, e podem ser colocados inclusive dentro do diretório do seu projeto, dessa forma, você pode fazer com que quando você acesse o diretório do seu projeto pelo shell da sua máquina ele posicione o seu RVM na versão correta do seu ruby e também na gemset adequada.

Vale a pena dar uma olhada no site oficial para saber mais, tem muitas outras funcionalidades no RVM que podem ajudar bastante no desenvolvimento.

Editado: Existe uma forma mais simples de mostrar a gemset no PS1. Basta adicionar o parâmetro “g” ao rvm-prompt. Dessa forma, ficará:

export PS1='\w `~/.rvm/bin/rvm-prompt i v g` `git branch 2> /dev/null | grep -e ^* | sed -E s/^\\\\\*\ \(.+\)$/\(\\\\\1\)\ /`\[33[37m\]$\[33[00m\] '
Obrigado Nelson Haraguchi por apontar.

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.