De artista.frustrado
OBS: este documento ainda está em constante atualização
Tabela de conteúdo |
Definição
Segundo a definição da W3C um Web Service é um sistema de software projetado para suportar interoperabilidade máquina-para-máquina através de uma rede. Frequentemente são API's Web que podem ser acessadas via uma rede, como a Internet, e executadas em um sistemas remoto que hospeda os serviços requisitados.
Funcionamento
Na programação tradicional o programa roda todo no computador do usuário, acesando bibliotecas e recursos locais.
Em um sistema baseado em consumo de Web Service o programa roda até o momento em que tem que buscar algum recurso no servidor, faz a requisição, recebe a resposta e continua o processamento.
É claro que para que essa divisão de trabalho seja efetivada novas camadas devem ser adicionadas ao programa, o que a princípio aumenta a complexidade do programa como um todo. O programa cliente chama o recurso no servidor fazendo a requisição a um proxy (agente que trabalha como intermediário entre o servidor e o cliente, ocultando toda a complexidade das operações), o qual serializa a requisição e a repassa ao servidor via o protocolo HTTP. O servidor chama as rotinas requisitadas e retorna os dados serializados, via HTTP também. O cliente recebe os dados do proxy, já desserializados e continua o processamento.
Proxy, em inglês, refere-se a algo ou alguém que atua em nome de outra pessoa. Em computação é um agente (interface ou serviço) que que repassa as requisições para outro agente.
Mas na prática, como isso funciona? Vamos ver um exemplo simples:
Exemplo de programa local
Abaixo vemos o código, em python de uma simulação uma calculadora com as 4 operações básicas:
#!/usr/bin/env python def soma(valor1, valor2): return valor1 + valor2 def subtracao(valor1, valor2): return valor1 - valor2 def multiplicacao(valor1, valor2): return valor1 * valor2 def divisao(valor1, valor2): return valor1 / valor2 if __name__ == '__main__': print soma(4, 5) print subtracao(5, 3) print multiplicacao(4, 5) print divisao(10, 5)
Tudo é executado no computador do usuário.
Exemplo básico utilizando python e XML-RPC
Abaixo temos o mesmo programa como um WebService utilizando XML-RPC. Preste atenção em na importação da biblioteca xmlrpclib a qual encapsula todos os procedimentos necessários para requisitar o processamento no servidor repassando e recebendo os dados do resto do programa.
No servidor instância da classe SimpleXMLRPCServer necessita que as funções sejam registradas para que possam ser expostas para o cliente.
Servidor:
#!/usr/bin/env python import xmlrpclib from SimpleXMLRPCServer import SimpleXMLRPCServer def soma(valor1, valor2): return valor1 + valor2 def subtracao(valor1, valor2): return valor1 - valor2 def multiplicacao(valor1, valor2): return valor1 * valor2 def divisao(valor1, valor2): return valor1 / valor2 server = SimpleXMLRPCServer(("localhost", 8000)) print "Listening on port 8000..." server.register_function(soma, "soma") server.register_function(subtracao, "subtracao") server.register_function(multiplicacao, "multiplicacao") server.register_function(divisao, "divisao") server.serve_forever()
Cliente:
#!/usr/bin/env python import xmlrpclib proxy = xmlrpclib.ServerProxy("http://localhost:8000/") print str(proxy.soma(100, 100) print str(proxy.subtracao(100, 100) print str(proxy.multiplicacao(100, 100) print str(proxy.divisao(100, 100)
Agora nós temos um sistema baseado em arquitetura cliente/servidor. Para isso adicionamos mais um elemento na chamada das funções, um proxy.
Exemplo básico utilizando python e SOAP
Servidor:
#!/usr/bin/env python import SOAPpy def soma(valor1, valor2): return valor1 + valor2 def subtracao(valor1, valor2): return valor1 - valor2 def multiplicacao(valor1, valor2): return valor1 * valor2 def divisao(valor1, valor2): return valor1 / valor2 server = SOAP.SOAPServer(("localhost", 8080)) server.registerFunction(soma) server.registerFunction(subtracao) server.registerFunction(multiplicacao) server.registerFunction(divisao) server.serve_forever()
Cliente:
#!/usr/bin/env python import SOAPpy proxy = SOAPpy.SOAPProxy("http://localhost:8080/") print str(proxy.soma(100, 100) print str(proxy.subtracao(100, 100) print str(proxy.multiplicacao(100, 100) print str(proxy.divisao(100, 100)
Exemplo basico utilizando C# e mono
Servidor:
Crie um arquivo chamado Matematica.asmx com o codigo abaixo:
<%@ WebService Language="C#" Class="Matematica.Matematica" %> using System; using System.Web.Services; namespace Matematica { [WebService (Namespace = "http://artista.frustrado.com.br.org/Matematica")] public class Matematica : WebService { [WebMethod] public int soma (int number1, int number2) { return number1 + number2; } [WebMethod] public int subtracao (int number1, int number2) { return number1 - number2; } [WebMethod] public int multiplicacao (int number1, int number2) { return number1 * number2; } [WebMethod] public int divisao (int number1, int number2) { return number1 / number2; } } }
Abra um console e entre na pasta em que colocou o arquivo e rode o servidor http do mono, o xsp. No exemplo abaixo iremos utilizar o xsp2, versao do xsp do mono2.
xsp
Agora abra um navegador, como o Mozilla Firefox por exemplo, e acesse o endereço http://localhost:8080/Matematica.asmx e voce podera navegar atraves da descricao do servico assim como visualizar o WSDL do mesmo.
Como C# e uma linguagem estaticamente tipada torna-se necessario recriar os objetos que iremos acessar no servidor construindo uma proxy. Para tanto iremos utilizar a ferramenta wsdl
wsdl2 "http://localhost:8080/Matematica.asmx?wsdl=0"
Ira importar a descricao do servico e gerar o codigo de proxy, a classe Matematica como definida no servidor.
using System; namespace Matematica { public class Cliente { public static void Main( string[] args ) { Matematica cliente = new Matematica(); Console.WriteLine(cliente.soma(100, 100)); Console.WriteLine(cliente.subtracao(100, 100)); Console.WriteLine(cliente.multiplicacao(100, 100)); Console.WriteLine(cliente.divisao(100, 100)); } } }
E para compilar execute:
gmcs2 Matematica.cs -r:System.Web.Services Cliente.cs
Exemplos Práticos
Cadastrar imagens no picasaweb
Faça o download e instale a biblioteca gdata
Caso esteja utilizando linux:
wget http://gdata-python-client.googlecode.com/files/gdata.py-1.2.4.zip unzip gdata.py-1.2.4.zip cd gdata.py-1.2.4 python setup.py intall
Exemplo de cliente que lista os seus albuns:
#!/usr/bin/env python import gdata.photos.service import gdata.media import gdata.geo username = "seulogin" password = "suasenha" gd_client = gdata.photos.service.PhotosService() gd_client.email = "%s@gmail.com" % username gd_client.password = password gd_client.source = 'tutorial_frustrado_01' gd_client.ProgrammaticLogin() albums = gd_client.GetUserFeed(user="seu-login") for album in albums.entry: print 'title: %s, number of photos: %s, id: %s' % (album.title.text, album.numphotos.text, album.gphoto_id.text)
Exemplo de cliente que cria um album e publica todas as imagens de seu desktop:
#!/usr/bin/env python import gdata.photos.service import gdata.media import gdata.geo import os, re username = "seulogin" password = "suasenha" caminhoOrigem = "%/Desktop" % os.environ['HOME'] gd_client = gdata.photos.service.PhotosService() gd_client.email = "%s@gmail.com" % username gd_client.password = password gd_client.source = 'tutorial_frustrado_01' gd_client.ProgrammaticLogin() album = gd_client.InsertAlbum(title='TutorialFrustrado', summary='Album criado pelo tutorial frustrado') album_url = '/data/feed/api/user/%s/albumid/%s' % (username, album.gphoto_id.text) files = os.listdir(caminhoOrigem) test = re.compile("\.(jpg|jpeg)$", re.IGNORECASE) files = filter(test.search, files) for file in files: photo = gd_client.InsertPhotoSimple(album_url, file, 'Uploaded using the API', "%s/%s" % (caminhoOrigem, file), content_type='image/jpeg') photos = gd_client.GetFeed('/data/feed/api/user/%s/albumid/%s?kind=photo' % (username, album.gphoto_id.text)) for photo in photos.entry: print 'Photo title:', photo.title.text