You are on page 1of 10

Uma visão pragmática

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.

Surgimento das arquiteturas


No final da década de 1990, aplicações distribuídas começaram a ser desenvolvidas com HTTP e XML.
Entretanto, isto era feito de forma customizada em todos os casos, com definição de protocolos próprios que
variavam de uma implementação para outra e de uma empresa para a outra. Em cada protocolo diferente
mudava também a abordagem de segurança, robustez, transações, entre outras coisas. Isto abriu uma
oportunidade para os fabricantes de middleware que desejavam vender seus produtos e serviços na área.
Mas eles precisavam de algo mais controlado para basear sua estratégia tecnológica.
Com o objetivo de padronizar estas implementações e facilitar a interoperabilidade entre sistemas e
empresas, foi iniciada a linha de arquitetura do WS-*. A razão da nomenclatura WS-* fica bastante clara
quando se pesquisa pelas especificações de web services definidas pelos grupos de estudos formados na área
e depara-se com a voracidade dos grupos em criar documentos e mais documentos padronizando coisas que
não estavam nem começando a ser implementadas.
O surgimento das especificações WS-* pode ser comparado com o do modelo OSI de 7 camadas. O modelo
OSI é uma ótima abstração e referência para um entendimento de como as redes de computadores
funcionam, mas ele foi definido teoricamente antes que houvesse implementações práticas o acompanhando.
Quando as implementações do OSI chegaram, eram grandes, lentas e frágeis, e acabaram sendo varridas do
mercado quando um concorrente mais simples e pragmático – o TCP/IP – se mostrou mais simples, eficiente
e robusto. O OSI acabou valendo apenas como um ponto de partida histórico, e até hoje, como um modelo
formal muito completo a partir do qual podem ser derivadas diversas tecnologias de rede.
De forma similar ao OSI, as especificações WS-* andaram muito mais rapidamente do que aplicações
baseadas nelas. Os comitês formados por várias empresas geraram uma massa extensa de documentos que
em boa parte não foram validados por uso extenso em aplicações reais. Por um lado, o WS-* oferece
soluções para praticamente todos os problemas imagináveis em arquiteturas SOA, inclusive recursos
sofisticados para transações e segurança. Por outro lado, quantas aplicações você conhece que realmente já
utilizaram estas especificações avançadas? A esmagadora maioria das aplicações da família WS-* só usa os
seus recursos mais básicos, como SOAP e WSDL.
Um caminho bastante diferente pôde ser observado no início dos RESTFul web services. Roy Fielding é um
dos principais autores do protocolo HTTP, e ele propôs em sua tese de doutorado um modelo de tecnologia
que faz extenso uso dos recursos oferecidos por este protocolo, que nos serviços padrão WS-* são muito
pouco explorados (inclusive porque o SOAP é independente de transporte; não precisa necessariamente
trafegar sobre HTTP, ainda que este seja o caso mais comum).
O desenvolvimento da abordagem REST de serviços foi bastante semelhante ao que ocorreu com a
arquitetura TCP/IP. No surgimento do TCP/IP, as implementações práticas foram surgindo e sendo refinadas,
e à medida que as tecnologias foram sendo adotadas com sucesso, se transformaram em especificações do
grupo Internet Engineering Task Force (IETF) para garantir a interoperabilidade entre implementações. Com
a abordagem REST, inicialmente havia apenas um conjunto de regras que ditavam como seriam os serviços
que seguissem esta linha de pensamento. Não havia inicialmente especificação para muita coisa, havia
apenas a tese defendida por Roy Fielding e então começaram a surgir aplicações desenvolvidas com esta
abordagem para resolver problemas reais.
À medida que a adoção de serviços REST foi aumentando, foram surgindo alguns padrões de implementação,
que indicavam como abordar alguns pontos que ficaram abstratos na tese original. Com os primeiros casos
de sucesso vieram os esforços de especificação mais precisa e padronização, para permitir o re-uso de idéias
nos traços comuns de todos os serviços e permitir que um nível de abstração superior fosse alcançado. Este
progresso levou à formação de grupos de estudo do IETF que estão atuando na padronização dos serviços
REST.
Analisando estes dois históricos, poderíamos talvez classificar o surgimento do WS-* como resultado de um
processo de desenvolvimento “waterfall”, no qual muito foi planejado e decidido antes de começarem as
implementações. Com os problemas e desafios enfrentados ao aplicar estas idéias em situações reais,
algumas especificações como SOAP e WSDL precisaram ser revistas várias vezes para transformar as
especificações complexas em serviços úteis, o que causou re-trabalho e o emprego de um esforço
considerável.
Por outro lado, o desenvolvimento dos serviços REST seguiu uma linha muito mais incremental, evolutiva.
Um conjunto pequeno de regras de fácil compreensão foi usado como ponto de partida, e então com a
evolução do entendimento do problema, a comunidade de pesquisadores e usuários da tecnologia pôde
identificar algumas questões de difícil decisão na arquitetura. Estas questões foram tendo soluções propostas
e documentadas à medida que se acumulavam os casos de sucesso na sua adoção.
Alguns conceitos de web services e especificamente alguns detalhes das abordagens WS-* e REST para
resolver alguns problemas são um tanto complicadas de se entender sem um exemplo real para mapear as
idéias. Nas próximas seções, descreverei a arquitetura dos dois estilos de tecnologia SOA, e ao longo do
processo usarei alguns exemplos de serviços fictícios do Submarino, envolvendo operações sobre produtos.

Arquitetura das tecnologias SOA WS-*


Após uma boa contextualização sobre a motivação para criação dos web services e um pequeno histórico do
surgimento dos dois estilos de arquitetura, precisamos detalhar bem mais as características de cada um para
podermos compará-los.
Uma visão geral de como ocorre a comunicação nos web services que utilizam SOAP pode ser vista na

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.

Figura 2. Formas de troca de mensagens com SOAP

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*.

Arquitetura dos web services REST


Enquanto a arquitetura dos web services WS-* se baseia em um protocolo bem definido e com regras
precisas quanto ao formato dos dados trafegados, seguindo padrões acordados em consórcios de grandes
corporações de tecnologia, a arquitetura dos web services REST é radicalmente diferente.
Uma frase que expressa a filosofia de implementação de web services WS* é: “Este é o protocolo e estes são
os padrões, você deve definir os serviços que deseja oferecer e os documentos que deseja trocar entre as
partes.”. Com os web services REST a frase seria algo como: “Use extensamente os recursos do HTTP,
identifique os recursos envolvidos nos seus serviços e defina qual será o protocolo de interação com estes
recursos”. Com base neste contexto, a arquitetura em alto nível dos dois estilos é ilustrada na Figura 3.
Figura 3. Estilo de acesso aos serviços com REST e 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.

Listagem 4. Resposta RESTful de consulta de produto no Submarino

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.

Recurso Método Representação Status Significado


200 Recurso encontrado com sucesso e retornado.
301 Recurso movido de local. Deve ser pega a URI
GET Produto que for retornada na resposta e passar a
utilizá-la em vez da URI anteriormente usada.
410 Recurso removido permanentemente.
200 Mesmo que no método GET.
Produto
301 Mesmo que no método GET.
PUT Produto
400 Requisição com formato inválido.
410 Mesmo que no método GET.
200 Recurso removido com sucesso.
DELETE -
204 Recurso não existe mais.
200 Busca bem sucedida, produtos retornados.
GET Produtos 301 Lista de produtos movida. Deve ser usada a
Produtos nova URI obtida na resposta para a busca.
201 Recurso criado com sucesso.
POST Produto
400 Requisição com formato inválido.
Tabela Q1. mapeia os recursos, métodos de requisição, status HTTP e o correspondente significado no
protocolo definido

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.

Serviços orientados a recursos e serviços orientados a atividades


Após discutir diversos aspectos de implementação e detalhes técnicos de algumas especificações e
protocolos, é interessante abordar também uma questão que foca mais no domínio do problema. A
necessidade de se oferecer serviços, realizar integração entre aplicações, plataformas e empresas vem
aumentando à medida que diversificamos a gama de topologias de implementação existentes. Com isso,
serviços dos mais variados tipos precisam ser criados e uma classificação interessante pode ser aplicada.
Alguns serviços são fortemente associados a recursos. No Atom Publishing Protocol, o objetivo é manipular
posts, comentários e feeds do formato Atom. Este é um tipo de serviço no qual saltam aos olhos os recursos
existentes e quais são as interações a serem realizadas sobre os mesmos. Sem dúvida há vários serviços que
se identificam bem com este perfil. Nesta linha de serviços, onde os recursos e as manipulações sobre os
mesmos ficam bem definidas, a modelagem de uma solução orientada a recursos com REST fica bastante
clara e interessante. Podemos fazer uso das capacidades do protocolo HTTP para chegar a uma arquitetura
bastante escalável, com uso de uma infra-estrutura comum na internet.
Entretanto, outros serviços são muito mais focados em atividades. Por exemplo, podemos ter um serviço do
Submarino que seja responsável por emitir pedidos de compra. Esta emissão de pedidos de compra pode ter
uma grande variedade de etapas, como notificar o sistema de cobrança, enviar e-mail para o usuário
confirmando recebimento do pedido, gerar ordem de entrega para a transportadora, etc. Apesar de ser
possível modelar todas estas etapas como recursos, certamente não é simples fazer isso. Em algumas
situações a modelagem em torno de recursos pode ser mais complexa e trabalhosa do que implementar os
serviços como atividades, uma característica forte dos serviços WS-*.
Um aspecto que não é muito considerado, mas impacta um pouco na facilidade de modelar os serviços como
recursos ou como atividades é a forma como a equipe de desenvolvimento recebe as especificações. Mesmo
que isto varie bastante de um lugar para outro, muitas vezes as solicitações de implementação são sob a
forma de Casos de Uso, e estes muitas vezes são mais próximos de descrições de atividade do que
descrições focadas em recursos. Os casos de uso costumam consistir em nomes de funcionalidades, como
Cadastrar Usuário, Emitir Relatório de Cobrança e Consultar Agendamentos de Execução.
Ainda que qualquer aplicação possa ser modelada de inúmeras maneiras, se você já recebe uma
especificação focada em um determinado modelo, o esforço para adotar outro modelo é um pouco maior.
Deve ser ressaltado que qualquer serviço, absolutamente qualquer um, pode ser implementado tanto com
REST ou com WS-*. O que deve ser considerado é qual das opções se aplica melhor às suas necessidades.

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

You might also like