Desenvolvimento - Web Services
Criando um cliente para Amazon Web Services (AWS) no Pocket PC
Recentemente eu adquiri um dispositivo IPAQ PocketPC, e depois de checar todos os aplicativos nativos, veio a idéia de criar meu primeiro programa usando o .Net Compact Framework (.Net CF)...
por Rodrigo VieiraEntre várias possibilidades, eu decidi pôr em prática uma idéia que sempre vinha à minha cabeça quando eu visitava livrarias em busca de livros técnicos importados, que é a possibilidade de checar a cotação (ou seja, o número de "estrelas") que o livro tem no site Amazon.com, que é um bom indicativo se o livro é bom ou se é uma "bomba".
A boa notícia é que a Amazon possui um conjunto de web services muito completo, "Amazon Web Services"(AWS), que permite checar todas as informacões relativos a livros, CDs e DVDs, bem como jogos e tudo mais que é vendido no site.
Tal aplicativo exige conexão à Internet, naturalmente, mas acredito ser uma questäo de tempo até as grandes lojas e shopping-centers no Brasil oferecerem serviço de internet wireless (Wi-Fi) para seus clientes, como já é comum nos EUA e Europa.
Apesar de ter sido escrito com .Net CF, o código que você verá abaixo é virtualmente idêntico ao que seria necessário em aplicacões ASP.Net e Windows.Forms (com excecão da interface com o usuário), e para quem não possui dispositivos móveis vale a pena lembrar que é possível usar emuladores para testar seus programas (veja como nesse ótimo artigo do site).
Vamos lá então!
1) Criando um projeto para aplicativos móveis, e adicionando a web reference à Amazon.com
O primeiro passo é criar um novo projeto no Visual Studio 2003: vamos selecionar "Smart Device Application" na janela "New Project" (dei ao projeto o nome de "Amazon"), e então "Pocket PC" para a plataforma-destino e "Windows Application" para o tipo de projeto.
Veremos então um windows.form em branco, e antes de mais nada podemos adicionar logo a web reference aos serviços da Amazon.com: na janela "Solution Explorer", clique com o botão direito do mouse no item "References" e então selecione "Add Web Reference". Entre o endereco para o web service, http://soap.amazon.com/schemas3/AmazonWebServices.wsdl, conforme a figura abaixo
Repare que esse servico expõe vários métodos, inclusive métodos avancados que permitem adicionar e alterar produtos no "carrinho de compras" e finalizar o pedido. Entretanto, em nosso programa nos ateremos às funções de procura. No campo "Web Reference Name", podemos alterar o valor para AmazonWS, mais amigável.
2) Criando um ID para o Amazon Web Services
Todo programa que acessa o AWS requer um ID único, que a Amazon utiliza para identificar as chamadas. Esse ID é muito fácil de ser obtido, e é gratuito. Basta ir nessa página e seguir as instrucões. Ao fim você receberá um e-mail com uma chave de identificacão (devtag).
3) Procurando livros com o AWS
Nosso aplicativo terá 2 funções:
- Procurar títulos por palavra-chave (título, autor, ISBN, etc);
- Ver os detalhes de um título, selecionado no resultado da busca.
Vamos então adicionar um TabControl ao formulário, composto por 2 abas: no primeiro será feita a busca, no segundo veremos os detalhes do livro selecionado.
Os botões "< Ant." e "Próx. >" permitem que o usuário navegue pelos resultados da busca sem ter que selecionar o título anterior ou posterior na primeira aba, tornando a navegacão mais cômoda, como num browser. Os demais controles adicionados são, acredito, auto-explicativos.
Terminada a interface com o usuário, podemos entrar com o código no arquivo .vb do formulário. Vamos começar pela funcão-chave de nosso código, que conecta ao web service da Amazon, e realiza busca por palavra-chave:
1 Dim products As AmazonWS.ProductInfo 2 Dim currIndex As Short 3 4 "--- essa constante eh o seu Subscription ID 5 Private Const DEVTAG = "XXXXXXXXXXXXXXXXXXXXX" 6 7 Sub SearchAmazon(ByVal str As String) 8 Cursor.Current = Cursors.WaitCursor 9 10 "---- define o parametro de busca 11 Dim keywordReq As New AmazonWS.KeywordRequest 12 With keywordReq 13 .type = "heavy" 14 .devtag = DEVTAG 15 .tag = DEVTAG 16 .mode = "books" 17 .locale = "us" 18 .sort = "reviewrank" 19 .page = 1 20 .keyword = str.Trim 21 End With 22 23 "---- conecta ao web service e realiza a busca 24 Try 25 Dim AmazWS As New AmazonWS.AmazonSearchService 26 products = AmazWS.KeywordSearchRequest(keywordReq) 27 Catch err As Exception 28 Cursor.Current = Cursors.Default 29 MsgBox(err.Message, MsgBoxStyle.Critical, "Erro na procura") 30 Exit Sub 31 End Try 32 33 "---- lista os resultados 34 If Not products Is Nothing AndAlso Not products.Details Is Nothing Then 35 For Each item As AmazonWS.Details In products.Details 36 lbResultado.Items.Add(item.ProductName) 37 Next 38 Cursor.Current = Cursors.Default 39 Else 40 Cursor.Current = Cursors.Default 41 MsgBox("Nenhum produto encontrado") 42 End If 43 44 End SubNo topo, declaramos uma variável global à aplicacão, "products", do tipo ProductInfo, que armazenará todos os produtos retornados pela busca.
A constante DEVTAG deverá ser preenchida com o seu Subscription ID, conforme explicado na seção 2 do artigo.
A busca no web service é feita pela funcão KeywordSearchRequest (linha 26), que recebe como parâmetro um objeto do tipo KeywordRequest que foi definido entre as linhas 11 e 21. O parâmetro "type" (linha 13) aceita 2 valores, "lite" e "heavy", sendo que o primeiro faz que a busca retorne apenas dados básicos sobre os títulos (nome, ISBN) e o segundo traz informacões completas, tais como cotacão, preco, reviews, etc. Como uma busca pode retornar muitos títulos, o servico retorna apenas 10 de cada vez, em "páginas" de 10 itens, por razões de tráfego: para buscar mais resultados, devemos setar o parâmetro "page" (linha 19) para a página desejada. No nosso caso, estamos interessados apenas nos 10 primeiros resultados, então fixamos page=1. Finalmente, o "keyword" contém a(s) palavra(s)-chave que queremos buscar.
Agora podemos fazer o primeiro teste! Vamos entrar "vb.net" na caixa de texto e apertar "Procura": após 2 ou 3 segundos, recebemos o resultado:
Perfeito! Agora podemos fazer o código que mostra os detalhes de um título selecionado. Os comentários no código explicam o que é feito em cada bloco.
1 Private Sub lbResultado_SelectedIndexChanged(…) 2 MostraDetalhes(lbResultado.SelectedIndex) 3 End Sub 4 5 Sub MostraDetalhes(ByVal index As Short) 6 "essa variavel controla qual item estamos vendo 7 "na lista "products" 8 currIndex = index 9 10 "desabilita o botao "< Ant" se o usuario estiver no 1o item 11 btAnterior.Enabled = (currIndex > 0) 12 13 "desabilita o botao "Prox >" se o usuario estiver no ultimo item 14 btProximo.Enabled = (currIndex < products.Details.Length - 1) 15 16 Dim currProduct As AmazonWS.Details = products.Details(currIndex) 17 With currProduct 18 lblTitulo.Text = .ProductName 19 20 "alguns titulos nao possuem informacao sobre autor, 21 "entao precisamos checar antes 22 If Not .Authors Is Nothing Then 23 lblAutor.Text = .Authors(0) 24 If .Authors.Length > 1 Then 25 lblAutor.Text &= " (et al)" 26 End If 27 Else 28 lblAutor.Text = "N/A" 29 End If 30 31 "o campo "Reviews" tb pode eventualmente 32 "vir em branco, embora nao seja comum 33 If Not .Reviews Is Nothing Then 34 lblCotacao.Text = .Reviews.AvgCustomerRating 35 Else 36 lblCotacao.Text = "N/A" 37 End If 38 39 lblPreco.Text = .OurPrice 40 lblISBN.Text = .Isbn 41 lblDisponibilidade.Text = .Availability 42 End With 43 44 "vamos selecionar a tab com os detalhes automaticamente 45 TabControl1.SelectedIndex = 1 46 End Sub
Podemos então testar o novo código, selecionando um dos títulos retornados pela busca:
Repare que o botão Anterior está desabilitado, pois estamos vendo o primeiro item da lista (linha 11).
Agora só falta fazermos o código para os botões "Ant" e "Próx", que é trivial:
1 Private Sub btAnterior_Click(…) Handles btAnterior.Click 2 If currIndex > 0 Then 3 MostraDetalhes(currIndex - 1) 4 End If 5 End Sub 6 7 Private Sub btProximo_Click(…) Handles btProximo.Click 8 If currIndex < products.Details.Length - 1 Then 9 MostraDetalhes(currIndex + 1) 10 End If 11 End Sub
4) Terminado o programa. Hora do "eye-candy"!
Bem, o nosso programa está pronto no que se refere a consumir os web services da Amazon.com, mas seria legal se pudéssemos também mostrar a capa dos livros, não?
Isso requer o uso da biblioteca System.Net do .Net Framework, e um trecho que código que permite salvar arquivos via HTTP. Também é bom criar uma variável do tipo Hashtable que funcionará como um cache de imagens, para que não tenhamos que baixar o mesmo arquivo duas vezes.
Então vamos adicionar um controle do tipo PictureBox na aba de detalhes, e o seguinte código:
1 Dim coverCache As New Hashtable "guarda todas capas ja baixadas 2 3 Private Function BaixaCapa(ByVal url As String) As Image 4 If url = "" Then 5 Return Nothing 6 Else 7 "se ja temos a capa no nosso cache, podemos retorna-la diretamente 8 If coverCache.Contains(url) Then 9 Return coverCache(url) 10 Else 11 Try 12 Cursor.Current = Cursors.WaitCursor 13 14 Dim webRequest As System.Net.HttpWebRequest 15 webRequest = System.Net.HttpWebRequest.Create(url) 16 "tenta acessar por 3 segundos no maximo 17 webRequest.Timeout = 3000 18 19 Dim webResponse As System.Net.HttpWebResponse 20 webResponse = webRequest.GetResponse 21 Dim bmp As New Bitmap(webResponse.GetResponseStream) 22 webResponse.Close() 23 24 Cursor.Current = Cursors.Default 25 If Not bmp Is Nothing AndAlso bmp.Width > 1 Then 26 coverCache.Add(url, bmp) 27 Return bmp 28 Else 29 coverCache.Add(url, Nothing) 30 Return Nothing 31 End If 32 Catch e As Exception 33 Cursor.Current = Cursors.Default 34 MsgBox("Erro baixando capa:" & e.Message) 35 Return Nothing 36 End Try 37 End If 38 End If 39 End Function
Para mostrar a capa na aba de detalhes, basta adicionar o comando
1 Dim capa As Image = BaixaCapa(.ImageUrlSmall) 2 pbCapa.Image = capa
entre as linhas 41 e 42 na funcão MostraDetalhes.
Testando o nosso programa, podemos agora ver a capa, o que torna o aplicativo muito mais atraente:
Bem, um último detalhe para deixar o programa realmente legal seria trocar o campo "cotação" por estrelas, como no site da Amazon, mas isso fica como exercício para você ;-)
Espero que este artigo seja útil!
Até a próxima.
- Verificando disponibilidade de um serviço WCF ou WebServiceC#
- Criando um WebService com ASP.NET Razor e WebMatrixWeb Services
- Construindo um List Suggest com ASP.NET Web Services e JQueryASP. NET
- Consumindo serviços REST com HttpClientWeb Services
- REST e o WSDLWeb Services