Dev (Back & Front)ARTIGO

Criando aplicativos da web com YQL e PHP – Parte 01

Atualmente, quase todos os Web sites populares têm uma API para
desenvolvedor, permitindo que programadores de aplicativo da Web acessem
e manipulem dados usando estruturas padrão, como REST e SOAP.

Por
exemplo, a Google oferece as APIs Google Data para acesso aos serviços
Google, como Google Buzz, Google Docs e Google Calendar. O Twitter tem
uma API REST que permite que os usuários busquem e postem tweets e o
Facebook oferece a API Graph para gerenciar perfis e conexões de
usuários.

Apesar de essas APIs certamente melhorarem sua vida e proporcionarem uma
variedade de novos aplicativos criativos, ainda existem alguns
desafios. Por exemplo, um desafio principal de implementação é a falta
de uniformidade entre as
APIs de diferentes sites.

Alguns sites usam REST, enquanto outros usam
SOAP. Alguns usam Atom para codificar dados de resposta, mas outros usam
RSS, e outros ainda usam XML simples ou JSON. Como resultado, toda vez
que você decidir integrar um novo serviço da Web em um aplicativo,
primeiro é preciso ler muito e, em seguida, testar bastante para
entender totalmente a mecânica da API de serviço antes de começar a
integração.

Para resolver este problema específico, os desenvolvedores da Yahoo!
decidiram inventar a Yahoo! Query
Language, mais conhecida pela sigla YQL. A YQL oferece uma interface
unificada similar à SQL para várias APIs de serviço da Web,
simplificando de forma significativa a tarefa de integrar dados de
terceiros em um aplicativo da Web.

Neste artigo em duas partes,
apresentarei a
YQL, ilustrando como é possível usá-la em combinação com minha linguagem
favorita, a PHP, para construir aplicativos da Web sofisticados.

Acrônimos usados frequentemente:

  • API: Application program interface
  • DOM: Modelo de Objeto de Document
  • ECS: E-Commerce Service
  • HTML: Linguagem de Marcação de Hipertexto
  • ISBN: International Standard Book Number
  • JSON: JavaScript Object Notation
  • RDBMS: sistema de gerenciamento de banco de dados relacional
  • REST: Representational State Transfer
  • RSS: Really Simple Syndication
  • SOAP: Simple Object Access Protocol
  • SQL: Linguagem de Consulta Estruturada
  • URL: Localizador Uniforme de Recursos
  • XML: Linguagem de marcação extensível

Entendendo YQL

Se estiver familiarizado com SQL, a YQL imediatamente parecerá
familiar para você. De forma muito simples, a YQL trata serviços da Web
individuais como se fossem tabelas de dados, permitindo que
desenvolvedores formulem consultas similares à SQL para extrair
informações.

O serviço YQL cuida da análise da sequência de consultas,
executando-a no serviço remoto, e retornando os resultados em formato
XML ou JSON padrão. A sequência de consultas em si é passada para o
serviço YQL usando REST, como uma solicitação GET.

Para entender melhor esta abordagem, considere um exemplo simples.
Suponha que deseje pesquisar no
Twitter todos os posts contendo o termo “master chief.” Sem o uso da
YQL, normalmente isto seria feito usando a API Twitter Search,
formulando uma solicitação como esta:

http://search.twitter.com/search.atom?q=master%20chief&lang=en

Como retorno, a API Twitter Search devolve uma feed Atom de resultados, como a da Figura 1.

Figura 1. Uma feed Atom de resultados da procura da API Twitter Search

Com YQL, é possível simplificar as coisas acessando a tabela de dados do Twitter com uma consulta YQL, da seguinte forma:

SELECT * FROM twitter.search WHERE q='master chief'

Note que isto é quase exatamente como uma consulta SQL padrão: a
palavra-chave SELECT indica que é uma operação de recuperação de dados, a
palavra-chave FROM especifica a origem de dados e a cláusula WHERE
especifica o filtro.

Depois de enviar esta consulta, a YQL
retorna um documento XML ou JSON padrão com os resultados de sua
consulta do Twitter, como a da Figura 2.

Figura 2. Os resultados de uma consulta YQL na tabela de dados do Twitter

Agora, vamos adiantar alguns dias e supor que você tenha decidido
adicionar mais alguns dados a seu aplicativo da Web. Especificamente,
suponha que gostaria de usar as informações de geocodificação que
acompanham os resultados da procura do Twitter para exibir também um
mapa da área geográfica de onde cada postagem se originou.

Além disso,
suponha também que gostaria de acompanhar os resultados da procura do
Twitter com uma lista de manchetes de notícias sobre o termo de procura
“master chief.”

Sem o uso de YQL, seria preciso gastar algum tempo lendo a documentação das APIs do
Yahoo! Maps e Google News antes de realizar esta tarefa. Com YQL, é tão simples quanto adicionar algumas consultas:

SELECT * FROM google.news WHERE q="master chief"

SELECT * FROM maps.map WHERE latitude="XX" AND longitude="YY"

A Figura 3 e a Figura 4 ilustram capturas instantâneas dos resultados da consulta.

Figura 3. Os resultados de uma consulta YQL na tabela de dados do Google News

Figura 4. Os resultados de uma consulta YQL na tabela de dados do Yahoo Maps

Os resultados da consulta nas Figuras 3 e 4
claramente indicam que o maior benefício da
YQL reside em apresentar uma interface unificada para serviços da Web de
terceiros.

Ao permitir a consulta a serviços de terceiros usando
sintaxe SQL comumente compreendida, a YQL economiza tempo e esforço e
facilita a integração de dados de diversas origens em um aplicativo da
Web.

A capacidade de selecionar XML ou JSON como formatos de saída
também é útil, permitindo maior flexibilidade e o uso de programação no
lado do servidor (PHP Perl, por exemplo) ou ferramentas do lado do
cliente (jQuery ou mooTools, por exemplo) para acessar e manipular os
dados resultantes.

Usando o YQL Console

A forma mais fácil de começar com YQL é por meio do YQL Console, uma
ferramenta online interativa que permite formular e testar consultas YQL
instantaneamente. O YQL Console localiza-se na Yahoo! Developer Network
e possui ferramentas de diagnóstico, consultas de amostra e uma lista
de tabelas disponíveis.

Para ver como esta ferramenta funciona, navegue para o YQL Console e
insira a seguinte consulta para obter uma lista de álbuns musicais
populares no momento:

SELECT * FROM music.release.popular

Ao enviar o formulário, a sequência de consultas é enviada para o
serviço YQL como uma sequência de consulta codificada com URL. O serviço
YQL, a seguir, procura a definição de tabela, realiza a consulta e
retorna os resultados. A Figura 5 ilustra como se parece a saída no YQL Console.

Figura 5. Saída da consulta no console YQL interativo

Usando YQL com PHP

Como a Figura 5
ilustra, a YQL pode retornar dados usando XML ou JSON. Ao construir
aplicativos da Web PHP, o XML é normalmente mais conveniente, pois o PHP
possui extensões de processamento XML integradas (SimpleXML, DOM ou
XMLReader) que podem ser usadas para analisar rapidamente o documento
resultante. Assim, a listagem 1 tenta realizar a mesma consulta com PHP e SimpleXML:

Listagem 1. Processando resultados YQL com SimpleXML

<?php
// execute query
// get list of 15 most popular music releases
// retrieve result as SimpleXML object
$xml = simplexml_load_file('
http://query.yahooapis.com/v1/public/yql?q=
SELECT * FROM music.release.popular
');

// iterate over query result set
echo '<h2>Popular Music</h2>';
$results = $xml->results;
foreach ($results->Release as $r) {
echo '<p>';
echo '<a href="' . $r['url'] . '">' . $r['title'] .
'</a> (' . $r['releaseYear'] . ') - ';
echo '<a href="' . $r->Artist['url'] . '">' . $r->Artist['name'] .
'</a> <br/>';
echo 'Current chart position: ' . $r->ItemInfo->ChartPosition['this'] .
' / Last chart position: ' . $r->ItemInfo->ChartPosition['last'];
echo '</p>';
}
?>

A listagem 1
é iniciada com a formulação de uma consulta para o serviço da Web YQL,
passando a mesma sequência de consultas codificada com URL usada no
exemplo anterior.

Esta solicitação é feita por meio da função simplexml_load_file(), garantindo, portanto, que o documento XML resultante seja
automaticamente analisado e convertido em um objeto SimpleXML.

O
restante do script, então, faz iteração no nó <results> do documento XML, imprimindo o título, link, artista e posição atual de cada álbum. A Figura 6. ilustra o resultado.

Figura 6. Uma lista de lançamentos de músicas populares, recuperadas por meio da YQL

Se você usar a Zend Framework, poderá, de forma alternativa, acessar o serviço da Web YQL usando o componente Zend_Rest_Client. A listagem 2, que produz saída equivalente a da listagem 1, ilustra isso.

Listagem 2. Processando resultados YQL com a Zend Framework

<?php
// set up Zend auto-loader
// load Zend REST client classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// execute YQL query
// get list of most popular music releases
try {
$client = new Zend_Rest_Client('http://query.yahooapis.com/v1/public/yql');
$client->q('SELECT * FROM music.release.popular');
$result = $client->get();
} catch (Zend_Rest_Client_Exception $e) {
echo "Client error: " . $e->getResponse();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}

// iterate over query result set
echo '<h2>Popular Music</h2>';
foreach ($result->Release as $r) {
echo '<p>';
echo '<a href="' . $r['url'] . '">' . $r['title'] .
'</a> (' . $r['releaseYear'] . ') - ';
echo '<a href="' . $r->Artist['url'] . '">' . $r->Artist['name'] .
'</a> <br/>';
echo 'Current chart position: ' . $r->ItemInfo->ChartPosition['this'] .
' / Last chart position: ' . $r->ItemInfo->ChartPosition['last'];
echo '</p>';
}
?>

O componente Zend_Rest_Client da Zend Framework foi projetado
especificamente para desenvolvedores que tentam integrar aplicativos PHP
com serviços da Web baseados em REST.

Com este cliente, é possível
realizar respostas GET, POST, PUT e DELETE para um terminal de serviço
REST. As respostas REST são retornadas como instâncias de objetos
Zend_Rest_Client_Response, o que torna fácil acessar propriedades de
respostas individuais.

A listagem 2
primeiro carrega as bibliotecas classe Zend e, em seguida, inicializa
uma instância da classe Zend_Rest_Client. Este cliente é usado para
inicializar uma solicitação GET não autenticada para o terminal do
serviço da Web YQL, como foi feito anteriormente na listagem 1.

O arquivo XML retornado é, então, analisado e convertido em um objeto
Zend_Rest_Client_Response, que pode ser processado usando um loop
foreach() padrão. Note que, ao usar o objeto Zend_Rest_Client, não é
necessário codificar com URL a consulta YQL, pois o componente se
encarrega daquela etapa internamente.

Filtrando e classificando resultados da consulta

Como com consultas SELECT regulares, a YQL permite filtrar resultados da
consulta com uma cláusula WHERE, especificar campos obrigatórios e
classificar resultados por um ou mais campos. Para ilustrar, considere a
seguinte consulta à API Flickr para obter uma lista de locais que
correspondam ao termo de procura “england”:

SELECT * FROM flickr.places WHERE query="england"

A Figura 7 ilustra a resposta da YQL a esta consulta.

Figura 7. Uma lista de resultados da procura por “england”, recuperada do Flickr por meio da YQL

A listagem 3 ilustra esta consulta na prática.

Listagem 3. Filtrando resultados YQL com uma cláusula WHERE

<?php
// set up Zend auto-loader
// load Zend REST client classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// execute YQL query
// get list of Flickr places matching search term
try {
$client = new Zend_Rest_Client('http://query.yahooapis.com/v1/public/yql');
$client->q('SELECT * FROM flickr.places WHERE query="england"');
$result = $client->get();
} catch (Zend_Rest_Client_Exception $e) {
echo "Client error: " . $e->getResponse();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}

// iterate over query result set
echo '<h2>Search Results</h2>';
echo '<table border=1>';
echo '<tr><th>Name</th><th>Latitude</th><th>
Longitude</th></tr>';
foreach ($result->place as $p) {
echo '<tr>';
echo '<td>' . $p . '</td>';
echo '<td>' . $p['latitude'] . '</td>';
echo '<td>' . $p['longitude'] . '</td>';
echo '</tr>';
}
echo '</table>';
?>

A Figura 8 exibe a saída formatada da listagem 3.

Figura 8. Uma lista formatada de resultados da procura por “england”, recuperada do Flickr por meio da YQL

 É possível adicionar critérios de filtro adicionais com operadores AND e
OR. Considere esta revisão da consulta anterior, que filtra
adicionalmente os resultados por fuso horário:

SELECT * FROM flickr.places WHERE query="england" AND timezone LIKE "%europe%"

É possível restringir a saída da consulta somente a campos específicos.
Esta abordagem é útil quando é necessário somente um pequeno subconjunto
dos dados retornados pelo serviço da Web e também reduz o tamanho do
pacote de resposta.

Segue uma revisão do exemplo anterior, que recupera
somente a latitude, longitude e o nome de cada registro:

SELECT latitude, longitude, content FROM flickr.places WHERE query="england"

A YQL também suporta várias funções de utilitário que podem ser usadas
para classificar, contar e eliminar duplicações do conjunto de
resultados. Essas funções são comumente colocadas depois da sequência de
consultas YQL, separadas por um caractere pipe (|).

Considere a
seguinte consulta, que classifica os resultados por latitude:

SELECT latitude, longitude, content FROM flickr.places 
WHERE query="england" | sort (field="latitude")

Também é possível aplicar o filtro para remover duplicações do resultado, especificando o campo que deverá ser verificado:

SELECT * FROM flickr.places 
WHERE query="england" | unique (field="timezone")

A listagem 4
reúne isto tudo em uma ferramenta de consulta interativa que pede ao
usuário que insira um nome de local e retorna uma lista classificável de
resultados.

Listagem 4. Procurando por nomes de lugares

<html>
<head></head>
<body>
<form method="post" action="<?php echo htmlentities
($_SERVER['PHP_SELF']); ?>">
Search term:
<input type="text" name="q" />
Sort results by:
<select name="s">
<option value="timezone">Time zone</option>
<option value="latitude">Latitude</option>
<option value="longitude">Longitude</option>
</select>
<input type="submit" name="submit" value="Search" />
</form>
<?php
// check if form is submitted
// perform necessary validation (omitted for brevity)
if (isset($_POST['submit'])) {
// set up Zend auto-loader
// load Zend REST client classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// execute YQL query
// get list of Flickr places matching search term
// sort by requested field
try {
$client = new Zend_Rest_Client('http://query.yahooapis.com/v1/public/yql');
$client->q(
'SELECT latitude, longitude, timezone, content FROM flickr.places
WHERE query="' . $_POST['q'] .'" | sort(field="' . $_POST['s'] . '")');
$result = $client->get();
} catch (Zend_Rest_Client_Exception $e) {
echo "Client error: " . $e->getResponse();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}

// iterate over query result set
echo '<h2>Search Results</h2>';
echo '<table border=1>';
echo '<tr><th>Name</th><th>Timezone</th>
<th>Latitude</th><th>Longitude</th></tr>';
foreach ($result->place as $p) {
echo '<tr>';
echo '<td>' . $p . '</td>';
echo '<td>' . $p['timezone'] . '</td>';
echo '<td>' . $p['latitude'] . '</td>';
echo '<td>' . $p['longitude'] . '</td>';
echo '</tr>';
}
echo '</table>';
}
?>
</body>
</html>

A Figura 9 ilustra a listagem 4 em ação.

Figura 9. Uma procura interativa e filtro de classificação para nomes de locais

Para obter uma lista completa de funções YQL, consulte o Guia de YQL ao final do artigo na seção Recursos e obtenha um link.

Um aplicativo de exemplo: Previsão do tempo por localização

Veremos agora como reunir tudo que você aprendeu até agora para construir um aplicativo simples com base em YQL usando PHP. A listagem 5
pede ao usuário que insira sua localidade em um formulário, e depois,
conecta-se ao serviço Yahoo! Serviço de previsão do tempo por meio da
tabela weather.bylocation e consultas para uma previsão do tempo local
para aquela localidade. Veja o código na listagem 5.

Listagem 5. Recuperando previsões do tempo por localidade

<html>
<head></head>
<body>
<form method="post" action="<?php echo htmlentities
($_SERVER['PHP_SELF']); ?>">
Enter city name:
<input type="text" name="city" />
<input type="submit" name="submit" value="Get forecast" />
</form>
<?php
// check if form is submitted
// perform necessary validation (omitted for brevity)
if (isset($_POST['submit'])) {
// set up Zend auto-loader
// load Zend REST client classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// execute YQL query
// get Yahoo! Weather forecast for selected zip code
try {
$client = new Zend_Rest_Client('http://query.yahooapis.com/v1/public/yql');
$client->env('store://datatables.org/alltableswithkeys');
$client->q('SELECT * FROM weather.bylocation
WHERE location="' . $_POST['city'] . '"');
$result = $client->get();
} catch (Zend_Rest_Client_Exception $e) {
echo "Client error: " . $e->getResponse();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}

// process and print query results
$data = $result->results->weather->rss->channel->item;
echo '<h2>' . $data->title . '</h2>';
echo $data->pubDate . '<br/>';
echo $data->description;
}
?>
</body>
</html>

Depois que o formulário da Web for enviado com um nome de cidade, a listagem 5
usa o componente Zend_Rest_Client para enviar uma consulta YQL para o
serviço do tempo.

A consulta usa a cláusula WHERE para filtrar o
conteúdo da tabela weather.bylocation e recuperar uma previsão do tempo
para o CEP especificado. O resultado da consulta é formatado e
apresentado como uma página HTML. A Figura 10 ilustra o resultado.

Figura 10. Previsões do tempo por cidade, recuperadas por meio da YQL

Note também que a listagem 5 adiciona uma nova variável à sequência de consultas, env. Esta variável é necessária porque a tabela de dados weather.bylocation é chamada de tabela de comunidade,
mantida pela comunidade e não pelo Yahoo! propriamente dito.

Como
resultado, o serviço YQL não reconhece, de maneira automática, a
localização da definição desta tabela. A variável
env é usada para especificar a localização dos arquivos
de definição de tabela.

Neste caso, a localização é Community Open Data
Tables do Web site da YQL, que serve como um repositório para todas as
tabelas da comunidade da YQL.

Usando consultas YQL aninhadas

O maior valor de um RDBMS tradicional vem de sua capacidade de reunir
tabelas individuais para criar diferentes visualizações dos dados
contidos nelas. E uma das melhores coisas sobre YQL é que ela permite
fazer a mesma coisa com serviços da Web.

Usando consultas YQL, é
possível combinar dados de vários serviços da Web para apresentar
visualizações úteis e novas de dados de terceiros.

Apesar de as possíveis aplicações deste recurso serem limitadas
somente por sua criatividade, um exemplo simples pode ajudar a
esclarecer o poder deste recurso.

Considere a listagem 6,
que pede ao usuário que insira o nome de um país e, a seguir, consulta o
serviço da Web de entrada para listar os eventos futuros daquele país.

Listagem 6. Buscando eventos por país

<html>
<head></head>
<body>
<form method="post"
action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>">
Search for events in:
<input type="text" name="country" />
<input type="submit" name="submit" value="Search" />
</form>
<?php
// check if form is submitted
// perform necessary validation (omitted for brevity)
if (isset($_POST['submit'])) {
// set up Zend auto-loader
// load Zend REST client classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// execute YQL query
// get list of events in requested country
try {
$client = new Zend_Rest_Client('http://query.yahooapis.com/v1/public/yql');
$client->q(
"SELECT * FROM upcoming.events
WHERE country_id IN
(SELECT id FROM upcoming.country
WHERE name = '" . ucfirst($_POST['country']) . "')");
$result = $client->get();
} catch (Zend_Rest_Client_Exception $e) {
echo "Client error: " . $e->getResponse();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}

// iterate over query result set
echo '<h2>Events in ' . ucfirst($_POST['country']) . '</h2>';
foreach ($result->event as $e) {
echo '<p>';
echo '<a href="' . $e['url'] . '">' . $e['name'] .
'</a> <br/>';
echo 'Starts: ' . date('d M Y', strtotime($e['start_date'])). '<br/>';
echo !empty($e['end_date']) ? 'Ends: ' .
date('d M Y', strtotime($e['end_date'])) . '<br/>' : '';
echo 'Location: ' . $e['venue_name'] . '<br/>';
echo 'Address: ' .
sprintf('%s, %s', $e['venue_address'], $e['venue_city']) . '<br/>';
echo $e['description'] . '<br/>';
echo '</p>';
}
}
?>
</body>
</html>

A listagem 6
usa duas consultas YQL aninhadas. A consulta interna acessa a tabela
de dados “upcoming.country” para recuperar o ID numérico correspondente à
cadeia de caractere de país inserida pelo usuário. Este ID numérico é, a
seguir, passado para a consulta externa para recuperar uma lista de
eventos vinculados ao ID daquele país.

A Figura 11 ilustra um exemplo do resultado.

Figura 11. Uma lista de eventos a serem realizados, que podem ser pesquisados por país

É importante notar que, tecnicamente, isto não é uma junção, mas uma
subconsulta. Quando este artigo estava sendo elaborado, a YQL não
permitia o vínculo de tabelas por meio de chaves comuns (uma junção),
mas somente usar os resultados de uma consulta dentro de outra (uma
subconsulta).

Um aplicativo de exemplo: Listas e preços de livros mais vendidos

Como você pode imaginar, a capacidade de combinar dados de várias
interfaces da Web usando sintaxe simples similar à da SQL é excelente
para os desenvolvedores de mashup.

Portanto, vamos considerar outro
aplicativo um pouco mais complicado: combinar dados das listas de livros
mais vendidos do The New York Times com informações de preços
do banco de dados da Amazon.com para apresentar uma visualização
composta de livros populares, seus preços e sua popularidade.

A primeira etapa na construção deste aplicativo é recuperar a lista atual dos livros mais vendidos do New York Times
. A YQL disponibiliza estas informações por meio de sua tabela
nyt.bestsellers, mas é preciso uma chave de API válida para executar
consultas nesta tabela.

Presumindo que você tenha esta chave (consulte Recursos
para obter um link que explica como obtê-la), é possível recuperar a
lista de livros de ficção de capa dura mais vendidos na semana de
21 de julho de 2010 usando uma consulta como esta:

SELECT * FROM nyt.bestsellers WHERE listname='Hardcover Fiction' 
AND date='2010-07-21' AND apikey='NYT-API-KEY'

A Figura 12 ilustra a saída desta consulta.

Figura 12. Uma lista dos livros mais vendidos do New York Times , recuperados por meio da YQL

Note que cada registro do resultado lista o número ISBN exclusivo do
livro. Estas são informações críticas para a segunda parte do
aplicativo, que precisa procurar o preço do livro em Amazon.com.

Recuperar dados de precificação de Amazon.com pode parecer uma tarefa
difícil à primeira vista, mas, na realidade, não poderia ser mais
simples. A Amazon.com expõe seu banco de dados de produtos para
desenvolvedores de terceiros por meio de seu serviço da Web Amazon ECS
(consulte Recursos
para obter um link e informações sobre como obter uma chave da API). E a
YQL inclui uma tabela de dados para a Amazon ECS, tornando possível
recuperar informações de precificação para um ISBN particular com uma
consulta como esta:

SELECT DetailPageURL, ItemAttributes, SalesRank, MediumImage FROM amazon.ecs 
WHERE AWSAccessKeyId='AWS-KEY' AND secret='AWS-SECRET-KEY'
AND ResponseGroup='Medium' AND Operation = 'ItemLookup'
AND ItemAttributes.Binding = 'Hardcover' AND ItemId = '1400065453'

A Figura 13 ilustra a saída desta consulta.

Figura 13. Dados de produto da Amazon.com, recuperados por meio da YQL

Deve estar claro que as duas consultas anteriores podem ser facilmente combinadas para produzir as informações necessárias. A listagem 7
tem o script completo. Lembre-se de substituir as chaves simuladas da
API nas consultas com suas próprias chaves antes de executá-las.

Listagem 7. Recuperando listas e preços de livros mais vendidos

<html>
<head>
<style type="text/css">
.item {
float: left;
width: 400px;
padding:10px;
}
.cover {
float:left;
padding: 5px;
border: solid 1px black;
}
.data {
margin-left: 150px;
font-weight: bolder;
}
</style>
</head>
<body>
<?php
// set up Zend auto-loader
// load Zend REST client classes
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Rest_Client');

// execute YQL query
// get list of NYT bestsellers
// retrieve image and price from Amazon.com
try {
$client = new Zend_Rest_Client('http://query.yahooapis.com/v1/public/yql');
$client->env('store://datatables.org/alltableswithkeys');
$client->q(
"SELECT DetailPageURL, ItemAttributes, SalesRank, MediumImage FROM amazon.ecs
WHERE AWSAccessKeyId='AWS-KEY'
AND secret='AWS-SECRET-KEY'
AND ResponseGroup='Medium'
AND Operation = 'ItemLookup'
AND ItemAttributes.Binding = 'Hardcover'
AND ItemId IN
(SELECT isbns.isbn.isbn10 FROM nyt.bestsellers
WHERE apikey='NYT-KEY'
AND listname='Hardcover Fiction'
AND date='2010-07-20')
| unique(field='ItemAttributes.Title')");
$result = $client->get();
} catch (Zend_Rest_Client_Exception $e) {
echo "Client error: " . $e->getResponse();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}

// iterate over query result set
echo '<h2>New York Times - Hardcover Fiction Bestsellers</h2>';
$count = 1;
foreach ($result->results->Item as $r) {
echo '<div class="item">';
echo '<img class="cover" src="' . $r->MediumImage->URL . '"/>';
echo '<div class="data">';
echo $count . '. ';
echo '<a href="' . $r->DetailPageURL . '">' .
$r->ItemAttributes->Title . '</a>';
echo ' - '. $r->ItemAttributes->Author . '<br/>';
echo 'Amazon.com Sales Rank: ' . $r->SalesRank . '<br/>';
echo 'Amazon.com Price: ' .
$r->ItemAttributes->ListPrice->FormattedPrice . '';
echo '</div></div>';
$count++;
}
?>
</body>
</html>

A listagem 7
combina as duas consultas anteriores usando a chave ISBN como o
denominador comum para produzir um resultado composto contendo títulos,
autores, imagens preços e classificações de vendas dos livros. Este
resultado é, a seguir, analisado e processado para gerar uma página HTML
(Figura 14).

Figura 14. Uma lista de livros mais vendidos, combinada com dados do produto por meio da YQL

Note que na listagem 7,
a consulta interna recupera especificamente somente os números ISBN-10
dos livros nas listas de livros mais vendidos. Como estas informações
estão alguns nós abaixo na árvore, a notação de pontos é usada para
indicar a posição hierárquica exata dos nós necessários para os
analisados da consulta.

Uma técnica similar é usada ao aplicar o filtro
exclusivo à consulta externa, com a notação de pontos usada para indicar
o campo pelo qual os resultados deverão ser filtrados.

Conclusão

Como esses exemplos ilustram, a YQL é uma ferramenta eficiente para
desenvolvedores de aplicativos da Web: ela apresenta uma interface
unificada para diferentes serviços da Web, permitindo um mecanismo de
consulta padrão similar à SQL que acelera o desenvolvimento e requer
menos informações sobre o serviço de destino.

É possível filtrar
resultados YQL com cláusulas WHERE e combinar, ou fazer “mash up”, de
dados de vários serviços por meio do uso de sub-selects. Adicione o PHP,
com suas eficientes ferramentas de processamento de XML, à equação e
você terá uma combinação com a qual até mesmo o desenvolvedor da Web
mais experiente aproveitará!

Os exemplos deste artigo não abrangeram todo o conteúdo. É possível
fazer muito mais com a
YQL, incluindo paginação de consultas de resultados, extração de dados
de documentos RSS, Atom, XML e
HTML e adição e modificação de dados com consultas CREATE e UPDATE.

Farei uma abordagem mais ampla na segunda parte deste artigo, então
volte logo.

Recursos

Aprender

Obter produtos e tecnologias

  • Estrutura Zend: Faça o download dos releases mais recentes da Zend Framework.

***

artigo publicado originalmente no developerWorks Brasil, por Vikram Vaswani

Vikram Vaswani é o fundador e Presidente da Melonfire,
uma empresa de serviços de consultoria com conhecimento especial sobre
ferramentas e tecnologias de software livre. Ele também é o autor dos
livros PHP Programming Solutions e PHP: A Beginners Guide.

é o portal de tecnologia da IBM para profissionais de TI de todo o mundo. Colabore, aprenda a criar aplicativos inovadores e compreenda tecnologias avançadas. Acesse mais artigos e tutoriais em www.ibm.com/developerworks/br

Ver perfil