Professional Documents
Culture Documents
Analisando as duas formas de implementação de web services para decidir onde a aplicação de
cada uma é mais adequada
Já há alguns anos o assunto das arquiteturas orientadas a serviços (service oriented architectures – SOA)
está em evidência. A necessidade de se construir aplicações distribuídas, porém, facilmente interoperáveis e
fracamente acopladas existe há um bom tempo, e tem sido progressivamente satisfeita por uma série de
tecnologias, da RPC e orientação a objetos aos web services. A arquitetura SOA é o último passo nesta
evolução, e se caracteriza por não ser uma nova linguagem, middleware, protocolo ou formato de dados.
Pelo contrário, é um paradigma que coloca a tecnologia em segundo plano e toma como eixo central os
processos de negócio, que serão satisfeitos por serviços implementados por componentes de software
discretos (aplicações). Este foco no negócio implica que não existe uma tecnologia exclusiva para
implementar aplicações SOA; se uma tecnologia única fosse imposta, por melhor que fosse, não teríamos um
SOA completo, pois haveria restrições de interoperabilidade com aplicações que, por qualquer motivo, não
pudessem se adaptar à nova tecnologia.
Mas o objetivo deste artigo não é oferecer mais um ponto de vista filosófico sobre o tema. Justamente por
ser este estilo de arquitetura bastante abstrato, surgem questões práticas de implementação. Dissemos que
o SOA não é uma tecnologia específica, mas certamente precisamos de alguma tecnologia concreta para
implementar aplicações com arquitetura orientada a serviços.
No sentido de implementar este modelo, surgiram duas linhagens de tecnologia fundamentalmente distintas.
A primeira delas foi o que chamamos de WS-*, pronunciado “WS asterisco”. Ou segundo as más línguas, “WS
death star”, o que representa o enorme conjunto de especificações de web services já publicadas. A segunda
forma de implementação de web services baseia-se no REpresentational State Transfer (REST), que defende
a exploração dos recursos do HTTP de forma extensa.
O foco deste artigo será analisar de forma imparcial as duas tecnologias e então tentar ilustrar os pontos
positivos e negativos de cada uma, dando uma visão pragmática do momento atual em que estamos com
relação a SOA.
Figura 1.
Figura 1. Fluxo de comunicação dos web services WS*
Neste fluxo, a primeira etapa é descobrir onde o serviço com o qual deseja-se comunicar está publicado. Esta
descoberta pode ser feita a partir de alguma documentação do serviço ou através de uma consulta a um
repositório UDDI.
UDDI, que significa Universal Description, Discovery and Integration, é um registro baseado em XML e
independente de plataforma que possibilita que companhias publiquem seus serviços disponíveis. O UDDI
permite consultar como serviços ou aplicações interagem, e foi desenhado para ser acessado através de
mensagens SOAP e fornecer os documentos WSDL referentes aos serviços em questão.
Tendo descoberto o local de publicação do serviço que nos interessa, conseguimos obter um documento
WSDL (Web Services Description Language).
O WSDL é um artefato muito importante dos web services WS-*, pois ele especifica de forma precisa as
operações que estão expostas nos serviços, mapeando de forma tão precisa quanto se deseje os formatos de
documentos de entrada e de saída das operações. É bom enfatizar este termo utilizado, pois uma das
principais características dos web services é a troca de documentos XML.
Não interessa se por trás da implementação do serviço está um servidor de aplicações Java serializando
objetos ou se está uma aplicação PHP gerando documentos XML com seus recursos de processamento de
texto ou até mesmo uma interface para algum sistema legado de tecnologia arcaica. As regras que definem a
comunicação especificam os documentos XML que precisam ser trocados, e isto permite que um amplo
conjunto de plataformas e aplicações estabeleçam conversações entre si.
Esta não foi a primeira tentativa de se padronizar comunicações remotas entre diferentes plataformas.
CORBA, RPC e COM foram outras iniciativas neste sentido, mas não tiveram muito sucesso. A grande
motivação para o sucesso atual dos web services é que houve um amplo consenso em torno da adoção de
documentos XML como padrão de comunicação, e então todas as iniciativas neste caminho ganharam muita
força.
Voltando ao WSDL, ele é muito importante por definir, de uma forma aceita universalmente, como será a
interação de clientes com os serviços que estamos oferecendo. Ao especificar no WSDL quais são os schemas
XML dos documentos que serão trocados e a cardinalidade precisa de cada elemento, conseguimos garantir
que qualquer cliente que entenda o padrão estabelecido será capaz de interpretar os documentos e
comunicar-se corretamente com nossos serviços. Além disto, a maturidade deste padrão traz a vantagem de
que já existem geradores de clientes em várias linguagens a partir de um documento WSDL.
Durante muito tempo esta foi e ainda é uma das vantagens dos web services WS-* sobre os RESTful.
Embora já exista a versão 2.0 da especificação WSDL que permite descrever também os web services REST,
isto ainda está sendo muito pouco adotado. De uma maneira geral, não existe um padrão sobre como
descrever o protocolo de comunicação a ser utilizado para conversação com web services REST.
O caso típico presente na absoluta maioria dos casos é: se você precisa se integrar com uma interface REST,
leia a documentação da mesma e implemente a conversação de acordo com as regras definidas no protocolo
dela. Você tem razão ao pensar que isto não é bom, pois a cada nova integração a ser feita poderá ser
necessário estudar um novo protocolo que não é padrão, e então a experiência prévia de outras
implementações bemsucedidas não será aplicada de forma tão direta. Na próxima seção veremos como este
problema está sendo contornado de forma inteligente pelas implementações REST mais recentes.
Um exemplo de documento WSDL de serviços de produtos do Submarino pode ser visto na Listagem 1.
A declaração das operações especifica outro aspecto importantíssimo, que são os formatos das mensagens
de solicitação e resposta de cada operação. Neste exemplo cada mensagem de solicitação ou resposta das
operações teve seu schema XML declarado no início do WSDL, o que permite visualizar de forma bastante
clara quais são os elementos esperados como entrada e saída das operações. Este documento especifica as
mensagens buscarProdutoRequest e buscarProdutoResponse (usados pela operação buscarProduto),
e cadastrarProdutoRequest e cadastrarProdutoResponse (usados pela operação cadastrarProduto).
Além disto, no WSDL consta a declaração do protocolo das mensagens (SOAP 1.1 no caso do exemplo) e
como as mensagens SOAP serão codificadas. Uma última declaração digna de nota é a declaração do serviço,
que informa inclusive o endereço de acesso ao mesmo.
Neste exemplo foram declarados alguns schemas próprios deste documento. A declaração destes schemas
não precisava ser feita no WSDL, mas decidi fazê-lo desta forma para ter uma clareza maior. Poderíamos
também ter importado schemas XML externos.
Tendo visto no que consiste um documento WSDL, podemos passar a falar das trocas de mensagens em si,
através de SOAP. O significado da sigla é Simple Object Access Protocol, mas isto deve ser guardado apenas
para fins históricos, pois “Simples” é só no nome.
SOAP é o protocolo padrão de troca de mensagens nos web services em geral (os não-REST, vale lembrar).
Este protocolo é transportado no corpo de algum outro protocolo, sendo que na quase totalidade dos casos o
outro protocolo é o HTTP. O uso de HTTP é uma forma muito conveniente de se trafegar mensagens SOAP,
pois é confiável, suportado em um vasto conjunto de plataformas e dispositivos e capaz de trafegar através
de quase todos os firewalls, pois dificilmente tráfego HTTP será restringido. Para fins de precisão, deve ser
dito que SOAP também pode ser trafegado nos protocolos SMTP, FTP, TCP/IP puro e possivelmente mais
alguns, mas o uso de outros protocolos no lugar de HTTP é definitivamente pouco comum.
Com esta estrutura de troca de mensagens, fica claro que o peso do protocolo e o peso do parsing XML é um
pouco maior do que nos RESTful web services, pois neste último é constituído apenas de HTTP e possui uma
camada de XML mais simples.
A troca de mensagens SOAP ocorre de forma unilateral ou bilateral, conforme a Figura 2.
O padrão Request/Response de troca de mensagens pode ser síncrono ou assíncrono, ou seja, o nó que está
enviando a mensagem pode ficar aguardando a resposta do nó recebedor para continuar o seu fluxo de
processamento ou pode apenas enviar a mensagem assincronamente e continuar com o seu fluxo de
atividades normalmente.
No caso de SOAP em HTTP, o envio de mensagens é feito quase integralmente com uma solicitação HTTP
POST na qual o protocolo SOAP ficará dentro do corpo da solicitação e da resposta. Neste POST, o Content-
Type application/soap+xml é obrigatoriamente aceito por qualquer nó que processe mensagens SOAP. Pode
ser usado outro Content-Type caso se deseje, contanto que o mesmo permita ao menos incluir o conjunto de
informações SOAP padrão, com os elementos envelope, header e body. Claro, além desta exigência existe a
necessidade de todos os nós envolvidos serem capazes de interpretar o Content-Type escolhido para a
comunicação. Com qualquer escolha de Content-Type somos obrigados a iniciar o parsing XML da solicitação
e da resposta para descobrir os tipos de documentos XML que estão sendo efetivamente trocados na
comunicação. Posteriormente mostrarei como os serviços REST trouxeram uma maneira mais inteligente de
especificar isso fazendo uso dos recursos HTTP, mais especificamente, do Content-Type. Exemplos de
mensagens de solicitação e resposta SOAP podem ser vistos na Listagem 2 e Listagem 3,
respectivamente.
ultarProduto>
</soap:Body>
</soap:Envelope>
Listagem 3. Resposta SOAP de consulta de produto no Submarino
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body xmlns:submarino="http://www.submarino.com/produtos/Produto">
<submarino:consultarProdutoResponse>
<submarino:Produto>
<id>0321146182</id>
<descricao>Ipod Nano 2 GB</descricao>
<categoriaId>29</categoriaId>
<valorUnitario>400.00</valorUnitario>
<qtdEstoque>217</qtdEstoque>
</submarino:Produto>
</submarino:consultarProdutoResponse>
</soap:Body>
</soap:Envelope>
Mesmo que este processo de interpretar o XML da mensagem SOAP seja um pouco mais custoso do que o
parsing de um XML simples (sem as tags do SOAP) diretamente no HTTP, deve ser dito que o processo de
parsing de mensagens SOAP também tem suas vantagens comparando com a interpretação de mensagens
no estilo REST.
Devido ao enorme suporte aos padrões WS-* nas ferramentas e plataformas atuais, já existem inúmeras
ferramentas capazes de gerar código para o cliente e para o servidor de um determinado serviço a partir do
WSDL do mesmo. Claro que esta geração é apenas uma etapa inicial, e o desenvolvedor precisará customizar
os ítens gerados para atender às suas necessidades, mas o fato de já poder trabalhar diretamente na
linguagem e na plataforma final, sem precisar lidar com o parsing dos XMLs envolvidos é muito conveniente.
O suporte aos padrões WS* em ferramentas de integração, ESBs e BPMs é algo a ser considerado na escolha
da tecnologia também. Produtos deste nicho oferecem recursos muito interessantes e podem trazer um bom
ganho de produtividade e viabilizar alguns projetos que seriam muito complicados de se implementar com
desenvolvimento customizado. O suporte para REST vem aumentando constantemente e como este possui
uma estrutura mais simples, é provável que não demore muito até que o suporte a REST seja tão bom ou
melhor do que o suporte a WS*.
Enquanto nos web services com uso de SOAP a regra geral é fazer uma requisição HTTP POST com os dados
encapsulados dentro de outro protocolo, a regra com REST é que o método HTTP utilizado na requisição seja
relevante para decidir qual é a manipulação que se deseja fazer sobre os recursos em questão. Em vez de
declarar dentro de uma mensagem SOAP qual é a operação a ser invocada no serviço, esta declaração é feita
com uso dos métodos GET, POST, PUT ou DELETE na requisição HTTP e o serviço fará operações com base no
método escolhido.
Existem discussões sobre a melhor forma de se utilizar os métodos HTTP. Alguns defendem o uso dos quatro
métodos, com parte dizendo que o POST cadastra e o PUT atualiza e outros argumentam pelo contrário. E há
os que defendem o uso apenas de GET e POST.
Em cada implementação a decisão de como utilizar estes métodos HTTP fica a critério de quem estiver
definindo a arquitetura, pois, além disso, será necessário definir também o protocolo de conversação com os
serviços.
Uma opção que me agrada quando as restrições de segurança permitirem é o uso dos quatro métodos HTTP,
com GET buscando recursos, POST cadastrando, PUT atualizando e DELETE removendo. Uma motivação por
trás desta escolha do POST cadastrar e o PUT atualizar está presente na definição do HTTP. Na seção 9 da
RFC 2616, que aborda o HTTP, há a definição de que os métodos GET, HEAD, PUT, DELETE, OPTIONS e
TRACE são idempotentes.
Isto significa que várias requisições idênticas feitas em seqüência com estes métodos não devem causar
efeitos danosos no servidor. Sob este ponto de vista, N atualizações seguidas para um mesmo valor são
consideradas idempotentes, elas têm o mesmo efeito que uma única atualização. Já uma operação de
cadastro de forma alguma pode ser realizada N vezes em seqüência, pois isto terá o efeito de cadastrar N
vezes o mesmo produto, o que não é desejado.
Considerando estes argumentos e o fato de que o método POST não é especificado para ser idempotente, o
mais correto segundo a definição do protocolo é que o POST seja utilizado para a operação de cadastro nos
web services REST, e o PUT, por ser idempotente, ser utilizado para a operação de atualização.
Esta formulação assume que teremos liberdade de utilizar nas comunicações os quatro métodos HTTP
citados. Em muitas situações a segurança da rede pode bloquear tráfego de métodos diferentes de GET e
POST. Isto não invalida a ideologia da arquitetura, mas sem dúvidas forçará uma adaptação cuidadosa na
elaboração do protocolo de comunicação da sua aplicação.
Deve ser ressaltado que embora este tipo de mapeamento se assemelhe bastante às operações de um
clássico CRUD (create, read, update e delete), isto não implica necessariamente em um mapeamento dos
métodos HTTP para comandos SQL “correspondentes”.
Apesar de em alguns serviços simplórios as operações serem apenas as manipulações de um CRUD, esta
definitivamente não é a regra quando falamos de serviços corporativos do mundo real. Serviços corporativos
com domínios um pouco mais ricos terão tipicamente uma quantidade razoável de recursos envolvidos.
Mapear a interação entre estes recursos e definir como o estado de um recurso depende do estado de outro
é algo com grau de complexidade bastante superior ao de um CRUD, o que nos leva à discussão da seção
“Serviços orientados a atividades e serviços orientados a recursos”.
O paradigma REST
Após definir anteriormente como é uma mensagem SOAP típica, é necessário mostrar como é a troca de
mensagens em um protocolo RESTful. Uma das idéias principais aqui é que cada recurso possui uma URI,
que terá comportamentos diferentes dependendo do método utilizado para acessá-la e obviamente, dos
dados enviados na requisição HTTP. Para contextualizar um pouco este processo e facilitar o
acompanhamento, vamos retomar os exemplos de serviços do Submarino, manipulando produtos. Vamos
ilustrar serviços que busquem, cadastrem, atualizem e removam produtos e mostrar como fica a
implementação destes com uma abordagem REST.
O formato genérico de mensagem com REST é invocar uma determinada URI que referencia um recurso
utilizando um dos quatro métodos HTTP mencionados (GET, PUT, POST ou DELETE). Se for uma solicitação
HTTP GET ou DELETE, apenas a solicitação para uma determinada URI já é suficiente, pois o método HTTP
indica qual é a operação a ser realizada e também o recurso específico que estamos manipulando. Caso seja
uma solicitação de cadastro ou atualização (HTTP POST ou PUT, respectivamente), no corpo da requisição
serão enviados os dados necessários para a operação em questão.
Para mostrar isto de forma mais concreta, voltemos ao exemplo anterior da busca de produtos do
Submarino. Imagine que o Submarino ofereça também uma interface REST para integração com as suas
aplicações. Se você quisesse obter os dados daquele mesmo produto, você poderia fazer:
GET http://www.submarino.com.br/produtos/0321146182 HTTP/1.1
Nesta chamada, a URI de produtos é http://www.submarino.com.br/produtos. Nosso protocolo de
comunicação estaria definindo que um HTTP GET para esta URI adicionando o ID de um produto ao final da
URI obteria os dados de um produto específico. Um HTTP GET para a mesma URI, mas sem passar o ID do
produto retornaria todo o conjunto de produtos, ou um sub-conjunto com apenas os produtos ainda
disponíveis para venda.
Uma possível resposta a esta solicitação pode ser vista na Listagem 4.
HTTP/1.1 200 OK
Date: nnn
Content-Type: application/produto_submarino+xml; charset=utf-8
Content-Length: nnn
Last-Modified:
<?xml version="1.0" ?>
<produto xmlns="http://www.submarino.com/produtos/Produto" >
<id>0321146182</id>
<descricao>Ipod Nano 2 GB</descricao>
<categoriaId>Eletronicos</categoriaId>
<valorUnitario>400.00</valorUnitario>
<qtdEstoque>217</qtdEstoque>
</produto>
Repare no Content-Type declarado na resposta. Isto é algo definido pelo protocolo HTTP, e permite dizer já
em HTTP qual é o formato da mensagem que o cliente está recebendo. Isto significa que não precisaremos
fazer um primeiro nível de parsing para desencapsular o protocolo SOAP e só então descobrir qual é o
formato preciso de documento que está sendo recebido. Estamos informando isto já na camada HTTP, o que
torna certos cenários mais eficientes, por exemplo, implementação de componentes intermediários que
executam operações como roteamento ou filtro de mensagens, mas não consomem seu conteúdo. Não
estamos usando nada além de um recurso HTTP conhecido e largamente aplicado desde que o protocolo
deixou de trafegar apenas texto. Qualquer aplicação pode definir seus próprios Content-Types e fazer uso
desta facilidade.
Claro, para que isto funcione todas as ‘pontas’ da comunicação devem reconhecer este Content-Type mais
específico. Porém, em todas as conversações com web services os nós já conhecem previamente os tipos de
documentos que serão trocados, então a exigência de todas as partes reconhecerem o Content-Type não
dificulta de forma alguma o estabelecimento da comunicação.
Analogamente, caso um funcionário do Submarino quisesse cadastrar um novo produto no site, isto poderia
ser feito através de um HTTP POST para a URI /produtos, sem informar o ID (pois este ainda não existe). Ao
fazer este HTTP POST do cadastro, na resposta viria “HTTP/1.1 201 Created” e no header HTTP Location da
resposta viria a URI de acesso ao produto, algo como /produtos/654321, onde 654321 seria o ID do novo
produto cadastrado. Fazendo uma requisição HTTP GET para a URI /produtos/654321 obteríamos na resposta
os dados do produto em questão.
Através deste pequeno exemplo, podemos destacar outra característica importante dos serviços REST. O
status HTTP da resposta é bastante relevante. Por este status podemos inferir em muitos casos qual foi o
resultado da invocação ao serviço. Uma descrição mais completa deste modelo de comunicação pode ser
visto no quadro “Proposta de protocolo de comunicação com REST”.
Proposta de protocolo de comunicação com REST
Parte fundamental de uma arquitetura REST é a definição do protocolo de comunicação com os serviços de
interação com os recursos. A Tabela Q1 mapeia os recursos, métodos de requisição, status HTTP e o
correspondente significado no protocolo definido. O recurso Produto referese a uma instância específica, e o
recurso Produtos referese à lista completa de produtos.
Estes recursos dos métodos e status HTTP e também do Content-Type trazem um bom equilíbrio entre poder
e complexidade. O HTTP é um protocolo simples e de baixo overhead, e ao explorar bem suas capacidades, o
REST se torna ainda mais simples porque não precisa definir uma nova camada própria de headers (como a
que existe no SOAP).
Entretanto, o parsing do XML ao usar SOAP é em grande parte dos casos realizada diretamente pela
ferramenta ou API que o desenvolvedor estiver utilizando, e ele já recebe os dados em sua linguagem e
plataforma finais, prontos para serem utilizados. Ao criar um protocolo REST, você precisará cuidar
explicitamente da etapa completa de interpretação dos XMLs, o que traz um esforço extra de
desenvolvimento (mas é possível utilizar ferramentas de produtividade para XML, como JAXB para tradução
automática entre documentos XML e POJOs).
À medida que a adoção dos web services REST vai aumentando e a maturidade das implementações cresce,
vão surgindo algumas soluções para este problema. O Atom Publishing Protocol é um protocolo que define
regras de manipulação de posts, feeds e comentários no formato Atom. Como ele aborda de forma bastante
inteligente diversos aspectos envolvidos na criação de um protocolo de comunicação, o Atom Publishing
Protocol se tornou um “blueprint” de implementação de serviços REST. Muitos desenvolvimentos estão sendo
feitos com base no protocolo AtomPub, que embora foque originalmente em publicação de feeds e posts no
formato Atom, vem sendo generalizado e adotado em muitas outras situações.
O projeto open source Apache Abdera foi criado para oferecer uma API Java capaz de manipular os tipos de
recursos do Atom Publishing Protocol, e ele já implementa a camada de parsing XML de serviços do gênero.
O projeto ainda está incubado na Apache Software Foundation, e por enquanto possui apenas versões de
desenvolvimento, mas já vem sendo usado com sucesso para implementar serviços baseados no AtomPub e
está sendo integrado ao Mule ESB como ferramenta de web services. Provavelmente surgirão APIs para o
AtomPub em outras linguagens também, mas por enquanto esta é a única implementação.
Além desta solução através de protocolos de referência e APIs correspondentes para facilitar, com a chegada
da nova especificação WSDL 2.0, documentos WSDL serão capazes de descrever também serviços REST. Esta
especificação está evoluindo e sendo atualizada com uma freqüência razoável, mas oferece uma forma
padrão de definir tanto serviços WS-* como serviços REST. Isto sem dúvida facilitará muito o surgimento de
ferramentas para criação de web services REST, e de certa forma unificará parte dos esforços atualmente
divididos entre os dois estilos de serviços.
Conclusão
Este artigo teve como objetivo mostrar as características gerais dos web services REST e WS-*. Embora
numa discussão com esta extensão seja difícil analisar com nível suficiente de detalhes as vantagens e
desvantagens de cada forma de implementação, a idéia é ilustrar o padrão de abordagem que cada
tecnologia SOA utiliza e deixar a motivação para maiores detalhes de implementação de cada um dos estilos
em outros artigos.
De uma maneira geral, a escolha da melhor opção para cada caso específico depende bastante dos requisitos
da aplicação. A decisão de usar REST ou WS-* para um serviço é uma questão muito importante na definição
da arquitetura e este tipo de decisão deve ser tomado com base em questões técnicas, buscando resolver
um determinado problema da melhor forma possível.
Algo que acontece com certa freqüência é vermos pessoas se apaixonarem por uma determinada tecnologia
e então querer usá-la para tudo. Apesar disto ser compreensível, pois os bons profissionais de software são
apaixonados pelo que fazem, esta postura deve ser evitada. Algumas vezes presencio discussões fervorosas
e pessoas tentando sempre encontrar uma solução “RESTful” para qualquer problema que envolva web
services.
Os web services WS-* já apresentam alto grau de maturidade e estão à frente dos serviços REST em alguns
pontos. Entretanto, os serviços REST trazem simplicidade e mais poder. Com o surgimento do Atom
Publishing Protocol e outros “blueprints” trazendo boas práticas, amadurecem os desenvolvimentos na área.
Estamos caminhando para implementações mais simples e poderosas, sem perder o valor de padrões bem
aceitos e interoperáveis.
Minha sugestão é conhecer as duas formas de implementação de serviços, conhecer bem os requisitos por
trás deste tipo de problema e então basear suas decisões de arquitetura realmente nas necessidades que
você precisa atender. Decisões pragmáticas tomadas após uma boa análise têm muito mais chance de
sucesso do que decisões baseadas em qual tecnologia está “mais quente” no momento.
Continue acompanhando este fascinante tópico de SOA e web services, pois ele está apenas engatinhando no
Brasil e ainda promete crescer muito.
Links
http://bitworking.org/news/125/REST-and-WS
Artigo comparando REST com WS-*
http://bitworking.org/news/How_to_create_a_REST_Protocol
Descrição dos passos envolvidos na criação de um protocolo de comunicação com REST
http://www.ibm.com/developerworks/webservices/library/ws-restvsoap/
Análise de serviços orientados a recursos e serviços orientados a atividades
http://duncan-cragg.org/blog/post/getting-data-rest-dialogues/
Discussão entre arquiteto da ThoughtWorks e arquiteto do eBay sobre a adoção de serviços REST no eBay
em vez da API SOAP atual