Precisamos de um descritor de serviços REST?

Atenção, este blog foi migrado para: http://brunopereira.org

Me perguntaram sobre isso na minha apresentação de REST na Globo.com e isso foi assunto de uma discussão interessante hoje no CEJUG. Como é um assunto que pode interessar a bastante gente e eu me interesso muito por web services, resolvi falar mais sobre isso aqui no blog.

Os web services WS-* possuem o WSDL (Web Services Description Language), um artefato amplamente aceito que descreve de forma padrão os serviços da aplicação. 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 os 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.

Entretanto, WSDL (bem como muita coisa em WS-*) é complexo. Um ser humano que tenha que analisar um WSDL grande perderá um bom tempo para entender o que está descrito no documento. Já REST não tem uma forma padrão de especificar os contratos dos serviços.

Embora a versão 2.0 da especificação WSDL permita descrever web services REST, os principais projetos open source da área como o Apache Abdera, Google Data API, Jersey e o Mule não utilizam esta forma de publicação. Não tenho conhecimento de nenhum projeto publicamente divulgado que faça uso do WSDL 2.0 para descrever serviços REST, e a adoção desta capacidade é baixíssima (se é que existe).

O projeto Jersey oferece opcionalmente o WADL, que é uma forma de descrever serviços REST. Confesso que ainda não olhei o WADL para ver se seria interessante usá-lo. Pelo que sei, entretanto, a adoção dele também é muito baixa.

Existe também o documento de serviços do AtomPub, que é bem interessante. Ele é um documento simples que lista quais são as coleções disponíveis e a localização das mesmas. O documento informa também quais são os MIME types aceitos em cada coleção.

Eu considero interessante que a aplicação ofereça uma interface simples de consulta dos serviços disponíveis. Não é obrigatório, mas quando a aplicação tem uma certa quantidade de clientes é bem legal ter isso para facilitar.

Em dois projetos que eu trabalhei, eu implementei um Servlet simples que listava todas as URIs disponíveis na aplicação, quais métodos HTTP são aceitos em cada uma das URIs e além disso um exemplo de XML manipulado em cada uma das URIs. Isso foi algo que eu achei bom o suficiente, e não tão custoso. Normalmente a documentação de verdade dos serviços fica em algum lugar como uma Wiki, ou uma página qualquer com a descrição detalhada de como interagir com os serviços.

A questão principal é que quando você segue as boas práticas de desenvolvimento REST, os seus serviços ficam muito mais claros para quem precisa se integrar. Por exemplo, eu trabalhei em um projeto crítico de integração com o Google esse ano. Tive que usar várias funcionalidades da Google Data API. A API deles é REST, e encapsula os dados com o formato Atom. Eles não oferecem nenhuma interface semelhante ao WSDL, eles simplesmente têm uma página com a documentação dos serviços.

Como eles seguiram as boas práticas de implementação REST, eu rapidamente aprendi a utilizar a API deles. Os protocolos de comunicação REST são bem semelhantes, e mais simples de entender do que qualquer coisa com WS-*. Pouco mais de 1 hora depois de olhar a documentação deles, eu já estava conseguindo me integrar com eles, com os primeiros exemplos.

O Guilherme fez uma observação interessante durante a discussão disso na minha apresentação no Tech Talk. Quando você segue as boas práticas e implementa um protocolo conciso e claro, de certa forma podemos dizer que a implementação se “auto-documenta”. É algo que podemos traçar um paralelo ao que acontece ao utilizarmos Domain Driven Design. Aproximando a linguagem do código do domínio de negócio, facilitamos a compreensão da aplicação por pessoas que nunca a tinham visto antes. Uma boa arquitetura de web services declarativos (REST) fica muito mais clara do que uma arquitetura de web services imperativos (WS-*). Isto acontece porque com REST o que fica em destaque são os Recursos (que representam conceitos claros do domínio), em vez de Operações.

É claro que as pessoas ainda terão que ler um pouco da documentação, mas como os conceitos em sua maioria já estarão “no sangue”, as dificuldades iniciais são menores do que com WS-*.

O Felipe Gaúcho comentou no CEJUG sobre a capacidade de gerar clientes automatizados com WSDL. Embora isso seja verdade, no meu ponto de vista isso é meio que um mito. Não conheço ninguém que faça integrações automatizadas sem depender de seres humanos. A motivação disso é clara. Integrações envolvem regras de negócio, e ninguém que eu conheço faz negócios automáticos, sem definir as regras🙂

Existia o mito de que as aplicações “descobririam” serviços automaticamente com UDDI e se virariam para fazer as integrações, gerando os clientes automaticamente. Embora isso seja tecnicamente possível, na prática isso pra mim é uma viagem que serviria mais para desenvolvimento de inteligência artificial do que para web services propriamente🙂

Embora esta precisão do WSDL seja um ponto positivo, eu tenho a convicção de que a clareza que temos ao usar REST supera e muito as vantagens de termos geradores de clientes automatizados. Quanto a WS-* x REST de uma maneira mais geral, tem uma frase que eu gosto de utilizar. WS-* é apenas overhead a não ser que você tenha informações relevantes nos seus cabeçalhos SOAP. Se você nunca se preocupou MUITO (veja bem, MUITO) com o que está indo nos seu cabeçalhos SOAP, provavelmente um protocolo REST seria mais interessante.

Tem uma opinião a respeito disso? Estou ansioso para conhecê-la!🙂

18 respostas para Precisamos de um descritor de serviços REST?

  1. Rafael Ponte disse:

    Excelente post Bruno!

    É muito interessante como REST está “ganhando terreno” a frente de WS-* em muitas aplicações hoje em dia, pelo que vejo a maioria dos projetos fornecem recursos/operações simples, na qual WS-* seria um “overhead” como você mesmo diz.

    Acredito que um Wiki com informações sobre os serviços é algo realmente simples para um desenvolvedor que está acostumado a ler dezenas de papers, how-tos e documentações para poder utilizar decentemente algum framework hoje em dia🙂

    Enfim, parabéns pelo post, muito bom mesmo.

  2. Luca Bastos disse:

    Bruno

    Belo post. Concordo muito contigo

    Em um tutorial que dei sobre WS no ConexãoJava de 2006, disse que quanto mais estudava WS, mais acreditava em REST. Concordo também com o Dare Obasanjo quando disse que os maiores defensores de WS-* são aqueles cujos empregos ou clientes dependem disto.

    Discordo um pouco do Felipe Gaucho sobre o uso da palavra automatizado na capacidade de gerar clientes com WSDL. O chamado modelo de desenvolvimento “Start from WSDL” simplifica alguma coisa mas normalmente ainda dá bastante trabalho para implementar as interfaces e incluir lógica de negócio dentro das classes wrappers geradas. O uso da palavra “automatizado” dá a falsa impressão de que a vida é sempre simples como nos exemplos do tipo Hello World que aparecem por aí. Com WS-*as coisas nunca são simples.

    O WADL não é novo, ainda não pegou e nem sei se pegará, mas os autores do livro RESTful WS, que você já citou em outro post, defendem o uso de WADL como a solução mais simples e elegante para descrever os serviços(página 25). No capítulo 9 (que ainda não li) mostram um cliente para o del.icio.us usando WADL.

    Sobre a observação do GC sobre boas práticas acho que isto ainda não é muito comum com muita salada por aí e RPC demais para o meu gosto. Não é que ache que se deva banir totalmente o RPC mas acho que é uma coisa a ser evitada.

    PS: eitcha letrinha pequena aqui nos comentários do seu blog!

  3. Bruno,

    você já teve alguma experiência com WS-*?

    Seria interessante você elaborar um comparativo entre os graus de dificuldades das duas tecnologias, como transação, segurança, anexos, etc.

    Valeu pelo post!🙂

  4. Pontos em aberto sobre o REST:

    – validação de tipos e intervalos de dados
    – operações transacionais
    – interoperabilidade
    – número de chamadas ao serviço para simular transações e multiplos uploads (performance), e eventualmente descrição do serviço

    Procuro evitar sempre afirmações como “ganhando terreno”, ou outro tipo de expressão emocional que remete a um fetiche tecnológico.. isso diminui a qualidade da discussão.

    Já trabalhei em projetos REST e SOAP, e também já usei WSDL-Firts, Code-First ou REST definido em documento texto. No geral, o WSDL “defende” melhor a equipe de desenvolvimento, enquanto o REST joga toda a responsabilidade sobre os desenvolvedores e acaba gerando stress na equipe…. um escreve no documento, outro não lê ou entende errado e dê-lhe reuniões e brigas pra assumir o problema depois…

    Confesso que o WSDL exige um conhecimento sofisticado em XML para valer a pena. Discordo que o cabeçalho seja o grande trunfo do SOAP, na verdade o cabeçalho é mais usado para autenticação do cliente do que outra coisa. Na minha opinião, o grande conforto fica na validação embutida no contrato, e a capacidade de gerar serviço e proxy a partir de um único documento. Geralmente eu forneço aos desenvolvedores o WSDL e os testes de aceitação, e fico tranquilo que independente do que o desenvolvedor invente, o resultado final vai ser válido segundo o contrato. (ok, não existe esta pureza toda, mas o caos em torno de serviços definidos pelo WSDL tem sido menor que o caos de serviços desenvolvidos a partir de descrições em documentos texto)

    Atualmente trabalho com SOAP no emprego (WCF + CXF + Groovy), e desenvolvo meu protótipo open-source no CEJUG usando JAXWS. Sinto mais conforto usando JAXWS do que qualquer outra coisa que já tenha tentado ou forçado a tentar🙂

    Quem quiser conferir o que estamos fazendo com JAXWS, todo o código fonte e a pouca documentação estão disponíveis no site do Cejug-Classifieds: https://cejug-classifieds.dev.java.net/

    Bom post, boa discussão, parabéns ao Bruno pelo tempo de escrever o bom texto..

    valeu,

    Felipe Gaúcho
    Coordenador CEJUG

  5. um ultimo detalhe:

    O JAXWS provê o binding em SOAP e REST, (dual binding, semelhante ao AXIS). Estou planejando usar isso no classifieds, a partir da seguinte estratégia:

    – REST: operações de somente leitura e não transacionais (algumas)
    – SOAP: operações de escrita e/u transacionais (todas)

    Ou seja, o serviço vai ser soap 1.2 por default, mas algumas operações como leitura de RSS ou ATOM e que podem ser consumidas por agregadores já existentes e baseados em HTTP requests, eu pretendo liberar uma segunda forma de acesso..

    Não tive tempo de tentar ainda, mas acho que se for possível a custo baixa, seria uma ótima opção para os consumidores…

  6. blpsilva disse:

    @Rafael Ponte

    Realmente REST tem ganho bastante adesão ultimamente, pois as implementações estão amadurecendo e as pessoas estão percebendo o poder que esta linha de serviços traz.

    Para alguns serviços com requisitos bem especiais, temos que utilizar alguns recursos do WS-*, pois implementar de forma customizada com REST seria inviável. Entretanto, estes casos são bem poucos, e de uma maneira geral hoje em dia eu só utilizaria WS-* se precisasse me comunicar com algum serviço existente implementado desta forma. Tendo a liberdade de definir qual é a forma de integração, REST all the way.

  7. blpsilva disse:

    @Luca

    Realmente é difícil querer seguir com WS-* depois de conhecermos verdadeiramente o que pode ser feito com REST. Como você bem citou, a maioria das pessoas lá fora que defende ferrenhamente a continuidade de WS-* está fazendo isso por uma questão de preservar os investimentos já feitos, em vez de mérito técnico.

    Sobre o WSDL first, alguns comentários. Escrever um WSDL grande na mão é uma tarefa custosa. Eu já fiz isso em um projeto, e me tomou um bom tempo até acertar todos os detalhes que eu fui revisando. Você consegue gerar os esqueletos dos serviços e dos clientes depois, mas ainda tem que customizar a parte de negócio, e isso é que costuma ser o mais importante para qualquer projeto.

    Uma abordagem que eu utilizei em outras vezes foi começar “Bottom-Up”(escrever as classes e gerar o WSDL a partir delas), e aí adaptar o WSDL gerado e usar a forma “Top-Down” (gerar as classes a partir do WSDL). Isto foi bem mais prático, e seria a forma que eu utilizaria em novos projetos.

    Sobre o WADL, eu lembro que já o olhei rapidamente um tempo atrás, não gostei e não cheguei a ver mais detalhes. Eu tinha desgostado o suficiente para nem querer ver mais detalhes. Entretanto, o Jersey está oferecendo suporte a WADL (provavelmente porque o líder do projeto Jersey é o criador do WADL) e eu preciso olhar com calma depois para conhecer melhor os detalhes e ter uma opinião melhor formada sobre o assunto.

    Realmente ainda temos muita “salada” por aí, como você bem falou. Mas aos poucos as implementações REST vão evoluindo e as boas práticas ficarão mais comuns.

    OBS. a fonte dos comentários estava muito pequena mesmo, mas consegui ajustar no CSS aqui do blog😉

  8. blpsilva disse:

    @Rafael Carneiro

    Eu tenho experiência com WS-* sim. Já trabalhei com isso em 3 projetos e além disso já estudei bastante sobre o assunto, fazendo alguns experimentos.

    Já utilizei o Axis 2, o XFire e olhei um pouco o JAX-WS. Só recentemente estou conseguindo usar Java 5 no trabalho, e então o JAX-WS não era uma opção para mim nos projetos que usei o Axis 2 e o XFire. Entre o XFire e o Axis 2, o XFire é mais fácil, mas te dá menos controle. O Axis 2 permite que você gere bastante coisa, mas te deixa manipular tudo que ele gera. O XFire esconde bem mais as coisas. O JAX-WS é bem legal e produtivo, e considero a melhor opção se você pode usar Java 5.

    Sobre o comparativo que você falou, seria interessante mesmo. Só não creio que terei tempo para preparar algo assim tão cedo. Estou penando para ter tempo de escrever os últimos artigos da JM, e esse comparativo tomaria um tempo bem grande. Vou considerar isso pro futuro de médio prazo🙂

  9. blpsilva disse:

    @Felipe

    Bom, sobre as suas considerações:

    * Com REST você consegue validar qualquer coisa, não tem nenhuma restrição quanto a isso. Se vier qualquer coisa inválida, retorne um HTTP 400 (Bad Request) e indique qual foi o erro.

    * Não entendi bem as suas considerações quanto ao número de chamadas ao serviço, mas eu fiz testes de carga nos meus serviços REST que falam com o Google e com 150 threads fazendo requisições simultâneas aos serviços, tudo estava se mantendo sem problemas. E os serviços estavam rodando em uma máquina desktop nada parruda. A escalabilidade horizontal com REST é bem alta, de uma maneira geral.

    * Quanto a interoperabilidade, se você precisa se comunicar com um serviço WS-*, use WS-* e ponto final. Não tem margem pra escolha. Agora se você pode definir os contratos e o protocolo, REST te garante comunicação com mais clientes. Quase qualquer coisa sabe falar HTTP, mas não é tão fácil falar SOAP.

    Sobre a questão transacional, depende do que você quer. Se você está falando da transação que ocorre dentro do servidor onde rodam os serviços REST, você tem inúmeras maneiras de controlar a transação DENTRO deste servidor. Agora, se você quer que a transação da aplicação cliente e da aplicação servidora seja uma só, realmente será complicado.

    Se você precisar ter um controle transacional na linha de “Business Activity”, do WS-Transaction, use WS-*, sem dúvida. Implementar este tratamento em um protocolo REST ainda é feito de forma customizada, e eu não encararia uma encrenca dessas. Se sua aplicação tiver esses requisitos, use WS-Transaction, com as comunicações coordenadas com WS-Coordination, e Deus te abençoe!🙂

    Eu particularmente nunca peguei requisitos transacionais assim. Sempre tive requisitos transacionais isolados no cliente e no servidor. O que eu faço é controlar a transação da aplicação cliente de acordo com o resultado enviado pelo servidor remoto. Se o servidor remoto disse que a operação nele foi OK, você pode prosseguir com a transação no cliente. Se o servidor remoto indicou uma falha, você precisa tratar na aplicação cliente, da forma que for mais correta.

    Sobre os cabeçalhos SOAP, não é que eles sejam um trunfo. A questão é que quando você tem requisitos complexos como WS-Transaction, WS-Security ou logs de auditoria obrigatórios, você será obrigado a acompanhar esses cabeçalhos. Se você gosta de SOAP principalmente pela validação dos XMLs, acho que você deveria olhar REST com muito carinho, pois ele fará bem para a sua vida, seu humor, sua alegria em trabalhar..🙂

    Quanto ao duplo binding de JAX-WS, ele até existe, mas é muito limitado para serviços REST. É por isso que existe a JSR-311, que trata especificamente de serviços REST.

    Com JAX-WS, como você definiria que um serviço aceita somente HTTP PUT ou HTTP DELETE por exemplo? Como você conseguiria que os seus serviços recebessem JSON além de XML? Como você faria para gerar JSON e outros formatos além de XML? Como você conseguiria mapear os resultados das suas operações no servidor em diferentes status HTTP na resposta?

    Importante lembrar que WS-* é independente de transporte, embora use HTTP quase sempre. Sendo assim, os recursos do HTTP não são bem explorados com WS-*. Já REST é HTTP por definição, e explora muito bem os recursos do protocolo. Usar extensamente HTTP te dá mais poder. Se você pode usar HTTP, porque você precisaria de qualquer outro protocolo de transporte. WS-* tenta ser genérico demais, e por isso ficou tão complexo.

    Você pode utilizar JAX-WS para serviços REST, mas de uma forma muito limitada. Recomendo demais que você use JAX-RS (JSR-311) em vez de JAX-WS para REST.

    []s

    Bruno

  10. Felipe Gaúcho disse:

    * Com REST você consegue validar qualquer coisa, não tem nenhuma restrição quanto a isso. Se vier qualquer coisa inválida, retorne um HTTP 400 (Bad Request) e indique qual foi o erro.

    No SOAP nunca virá algo inválido porque os dados sao definidos num XML Schema.. Você nao perde tempo validando no servidor.

    * Não entendi bem as suas considerações quanto ao número de chamadas ao serviço, mas eu fiz testes de carga

    Num dos nosso projetos, depois de algum tempo curtindo a agilidade do rest, precisamos de transações.. entao simulamos transações usando uma mensagem para o serviço e uma segunda mensagem para confirmar a execução, e algumas outras mensagens para fechar todo o pacote de requisitos da operação.. ficou uma bagunça com baixíssimo desempenho.. acredite, os caras que inventaram a gambiarra eram REST fanáticos, os mesmos que convenceram a gente a usar REST desde o início..🙂

  11. Bruno, na minha opinião os serviços Rest devem possuir algum tipo de descritor. Tanto o Atom e o WSDL possuem a vantagem em relação ao WADL por serem padronizados, embora padrões muitas vezes não pegam. A documentação do serviço em formato Wiki também é bom (e necessário).

    Eu penso que no futuro nós teremos ferramentas que auxiliarão a composição de serviços, utilizando algo do tipo como BPEL, só que utilizando os descritores de Serviços Rest armazenados em algum tipo de Registro, como o Mule Galaxy ou WSO2 Registry. Desta forma, os descritores podem passar a ser fundamentais.

    []s

  12. blpsilva disse:

    @Felipe

    Sobre a validação, de fato com WS-* você pode validar diretamente pelo Schema XML. Com REST você também pode fazer isso, mas terá que ser explicitamente.

    Sobre a questão transacional, não posso falar tão bem sobre o seu exemplo sem conhecer os detalhes. Mas basicamente continuo com a minha opinião mencionada no comentário anterior. Se você precisar de transações “de longa duração”, que transcedam o escopo transacional de um único servidor (algo na linha do WS-Transaction Business Activity), então use WS-*. Eu não sou xiita, minha opinião é de resolver o problema da melhor forma. Se WS-* é mais indicado para o problema, go ahead and use it.

    Agora, minha opinião: os casos em que você de fato precisa dos recursos altamente sofisticados do WS-* são uma pequena minoria. E se por acaso os fanáticos por REST que você mencionou não tinham conhecimento suficiente para modelar bem uma solução complexa com REST, não condene a abordagem por causa disso.

    Aplicações mal implementadas existem com qualquer coisa que você use. E se você continua achando que WS-* é melhor para você, siga utilizando-o. Felizmente os middlewares WS-* estão caminhando para mais simplicidade e aumentando a produtividade. Se você se sente mais confortável com WS-* e implementa soluções melhores com essa abordagem, seja pragmático, e a mantenha como sua preferência mesmo.

    Minhas preferências são bem diferentes das suas, mas respeito a sua opinião. O mais importante é entregarmos softwares de qualidade, com qualquer escolha tecnológica que seja feita.

  13. blpsilva disse:

    @Alexandre

    Também estou aguardando a chegada de produtos mais interessantes para REST. Tenho acompanhado os produtos da Mulesource e da WSO2, mas infelizmente não estou tendo tempo para avaliá-los adequadamente.

    Como eu falei, acho muito interessante um descritor sim, mas ainda não estou decidido por nenhum formato específico. Nas 2 vezes que implementei um descritor, este foi customizado e sem nenhuma preocupação em automação. O objetivo foi oferecer um descritor compreensível por seres humanos mesmo.

    []s

  14. “Olhem quantas coisas o ateniense precisa para viver!”

  15. Tem um post muito bom de um cara que eu li uma vez para complementar isso que você disse. Ele participou muito evangelizando WS-* e depois percebeu REST como uma alternativa mais leve.
    http://www.25hoursaday.com/weblog/2007/11/15/WSIsToRESTAsTheoryIsToPractice.aspx

  16. blpsilva disse:

    @Emerson

    Bem interessante o post do Dare Obasanjo mesmo. É interessante acompanhar caras que já estiveram muito envolvidos com WS-* e passaram a adotar REST depois de acumular frustrações com WS-*. Aprendemos muito com a experiência desses caras também.

    Exemplos de caras nessa situação que eu acompanho são o próprio Dare Obasanjo e mais:
    James Snell – http://snellspace.com/wp/
    Dan Diephouse – http://netzooid.com/blog/

  17. Bruno, vai ter mais matéria na JM sobre REST?

  18. blpsilva disse:

    Oi Milfont, vai ter sim. Na edição 57 (Maio) saem 2 artigos meus sobre Atom e AtomPub, que são relacionados com REST. E estou escrevendo para a edição 59 (Julho) um artigo sobre a JSR-311 e o projeto Jersey. Provavelmente virá mais coisa por aí no futuro, mas por enquanto tem esses que falei.

    []s

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: