Os 7 hábitos dos desenvolvedores de WebServices altamente eficazes

Esta semana tive o prazer de palestrar no Café Com Tapioca, evento do CeJUG realizado em Fortaleza. Estavam presentes dois conhecidos evangelistas da Sun: Reggie Hutcherson e Simon Ritter.


DSC01766 DSC01773
DSC01770 DSC01763

O agradecimento fica ao Rafael Carneiro, do PortalJava e do CeJUG, pela organização geral do evento. Agradeço também à equipe do grupo Fortes pela minha vinda ao Ceará: ao Clavius Tales, Igo Coelho, Antônio Israel, Ronaldo Moreira, Tiago Moraes, Rodrigo Maia e tantos outros. Vale reparar como a comunidade java cearense é ativa nos blogs! Nesse sábado também ministrei umworkshop sobre Arquitetura e Design Java aqui em Fortaleza.

Durante esses dias aqui, muitas pessoas perguntaram bastante sobre webservices: em especial JSON e Rest. Compilei alguns dos pontos que foram recorrentes nas discussões e considerados como boas práticas:

Cuidado com a granularidade – a granularidade do seu serviço não pode ser muito fina, caso contrário seus seviços sofrerão dos mesmos problemas que o EntityBean do EJB2 exposto remotamente: uma enorme quantidade de requisições serão disparadas para executar pequenas tarefas, como getters! Seus serviços devem realizar uma quantidade significativa de tarefas, para evitar um número alto de roundtrips!

Exponha serviços, não dados – é comum ouvir a frase “Vou criar webservices para expor os meus dados“. O grande perigo aqui é deixar toda a lógica de negócio na mão do cliente, o que descentralizará seu serviço e forçará o cliente a realizar muitas requisições ao servidor. Devemos expor serviços, e não dados em sua forma mais crua.

Nunca parsear WSDL/SOAP manualmente – antes das ferramentas que trabalham com webservices terem atingido sua maturidade, era muito comum ver por aí as pessoas gerando o SOAP manualmente, através de bibliotecas XML ou às vezes até mesmo concatenando String com o uso de StringBuffer! O SOAP é o protocolo de comunicação, e assim como quando você usa RMI/CORBA e você não enxerga absolutamente nada do JRMP/IIOP, você nunca deveria ter contato direto com o protocolo de comunicação! O SOAP e o WSDL devem ser utilizados por ferramentas, e não pela sua própria aplicação. Hoje em dia qualquer ferramenta como o Apache Axis, Apache CXF, ou mesmo o wsimport, que já vem no JDK 6, auxilia nossa tarefa de gerar Stubs que sabem trabalhar com o SOAP, sem que você nem mesmo precise ve-lo um dia. Se você está usando um servidor de aplicação, esta tarefa é ainda mais fácil, até mesmo para fazer o deploy do serviço.

Não enviar XML dentro de XML – outra prática comumente encontrada em aplicações antigas que usam Webservices: dentro do SOAP é enviado um outro XML como um dos parâmetros, então mesmo usando ferramentas para gerar os stubs você fica com uma String que dentro dela há um XML e este precisa ser parseado por sua própria aplicação. Isto é uma má interpretação do conceito que “Webservices é comunicação via XML“. Concordo que em alguns raros casos isso possa fazer sentido, como por exemplo se o valor do que você quer realmente é um outro XML, mas no geral isto é feito sem necessidade nenhuma, como é o famoso caso do WebService MS Office dos Correios do Brasil.

Considerar protocolo binário – são muitas as reclamações de que o SOAP acaba sendo um XML grande e pesado para ser transportado. Hoje em dia há muitas formas de contornar isso, como o uso do padrão Fast InfoSet para compressão do XML. Uma outra forma seria o uso de protocolos proprietários, como o AMF da Adobe, que é uma opção comum no uso do Flex.

Considerar não usar WSDL/SOAP – pelas diversas críticas a burocracia exagerada do WSDL/SOAP, muitas pessoas estão optando por usar algo mais simples, como o bom e velho XML (POX), JSON ou até mesmo uma forma qualquer de estruturar dados. Caso você precise de simplicidade e velocidade no desenvolvimento com outras plataformas, essa é uma boa opção. Cuidado: muita gente está considerando qualquer webservice que não use WSDL/SOAP como sendo REST. Os webservices do flickr e da Amazon são um bom exemplo: tudo é via GET (as vezes POST) e não há recurso identificado pela URI. Na verdade ele usa apenas um esquema HTTP+XML (POX), considerado apenas em parte como RESTful. Você pode ver que esses webservices são muito diferentes do modelo RESTful do Atom Publishing Protocol. Criar um protocolo realmente REST como este não é fácil: porém teremos esse trabalho bastante simplificado com a JAX-RS (JSR 311), e já podemos ver isso através do Glassfish Jersey.

Considerar usar JSONJSON é um formato que tem ganho muita popularidade. Não é a toa: além de ser um simples para debugar, parsear e gerar, com javascript basta fazer um eval em um resultado JSON que ele já estará pronto para usar. É uma excelente opção para o consumo via AJAX e criação de mashups. JSON tem ganho bastante força na comunidade Flex, tornando-o uma ótima opção como ponte entre Flex e Java. A escolha por JSON abre portas para muitos tipos diferentes de clientes, e em especial o browser, que é nossa plataforma global.

Update: numa abordagem mais REST, a granularidade pode ser sim fina (e focada nos dados), tomando cuidado para deixar isso explícito, e sempre atento aos headers que possibilitarão o cache.

20 Comentários

  1. Rafael de F. Ferreira 18/02/2008 at 07:10 #

    Oi Paulo. O evento parece ter sido legal, eh importante disseminar essas mensagens.

    Eu so fiquei com o pe(1) atras com relacao ao “Nunca parsear WSDL/SOAP manualmente”. Usar bibliotecas para marshalling (ou data binding) objeto/xml tem varios riscos, pode aumentar o acoplamento entre cliente e servidor e atrapalha a evolucao independente dos servicos. Por exemplo, em .net se vc mapear um enumerated type do xsd para um enum do C#, teu servico vai quebrar quando o xsd for modificado para incluir um caso novo. Um paper meio antigo que toca nesses assuntos eh o do Alpine. (o link pro paper parece quebrado agora).

    (1) Ainda tenho que configurar a acentuacao no solaris aqui, foi mal…

  2. Rafael Carneiro 18/02/2008 at 09:41 #

    Já conhecia o Paulo através de comunidades como o GUJ e PortalJava, tive a honra de conhecê-lo pessoalmente através deste evento. Sabia da sua competência, mas não sabia que essa sua competência ia além do que eu esperava.

    A sua palestra foi excepcional, deixando os participantes vidrados no conteúdo.

    Paulo, meus parabéns pela sua competência e espero que você venha mais vezes a Fortaleza.

    Um abraço,

  3. Felipe Gaúcho 18/02/2008 at 10:19 #

    Ponto negativo: induz os novatos a enxergarem o REST e o JSON como o santo graal 🙁

    Fora isso, as dicas sao boas.

    Quanto ao marshalling entre xsd e tipos, em cotnract-first isto é mandatório. Os problemas acontecem quando você usa code-first, e fica modificando os dois modelos: o WSDL e o código que originou o primeiro wsdl 🙂

    O acoplamento entre cilente e serviço eh o contrato (WSDL), e este deve ser o master mind da coisa toda… parsear wsdl na mão é suicídio..

  4. Leandro Silva 18/02/2008 at 11:56 #

    Esse post caiu como uma luva! rsrsrs

    Tem uns malukinhos aqui no trabalho que “precisam” lê-lo urgentemente…

    Valeu!

  5. Paulo Silveira 18/02/2008 at 16:23 #

    Oi Rafael. Acho que ai o problema é da sua ferramenta que nao foi boa o suficiente para ja pensar em pequenas modificacoes futuras. E uma alteracao no WSDL é uma quebra de contrato, o que é normal ter de regerar stubs (mas veja que empresas como a amazon lançam um NOVO wsdl, justo pra esse tipo de coisa acontecer).

    Felipe, repare que disse apenas para considerar JSON, Rest e o não uso do WSDL/SOAP. Eu também gosto bastante do contrato forte do WSDL, em vez do contrato “boca a boca” dos webservices que não possuem uma interface. Mas é fato que muita das empresas web tem tido melhores experiências e maior adoção com os webservices não-SOAP/WSDL.

    Obrigado pelos comentários…

  6. Rafael de F. Ferreira 18/02/2008 at 18:47 #

    Nao quero parecer que so estou criticando, Paulo, eu realmente acho que eh super importante passar para o pessoal estes conceitos sobre granularidade e servicos. Falando nisso, um link legal para uma boa descricao desse tipo de coisa, na linha do que vc esta falando.

    Agora, voltando a carga :), contract-first nao resolve todos os problemas de acoplamento, nao. Versionamento de servicos eh sempre um problema dificil. Publicar o contrato e nunca mais tocar nele por toda a eternidade eh uma alternativa viavel. Nesse caso, qq evolucao do sistema se dah publicando outra endpoint com outro contrato e esperando que os clientes migrem para ele. Esse tipo de coisa eh o mesmo que se faria com IDLs CORBA e sistemas analogos. Dependendo do alcance do servico vc pode acabar tendo que rodar um monte de versoes paralelamente para nao atrapalhar os clientes legados. A grande vantagem de document-orientation com XML eh que o formato permite a evolucao independente de clientes e servidores (ou seja, acoplamento mais baixo). Nao eh simples, mas eh perfeitamente possivel, veja por exemplo as extensoes do Atom (RFC-4685 eh uma). Os artigos do David Orchard sugerem umas tecnicas para evolucao de schemas.

    Agora, nao vejo nenhum impedimento a-priori para que ferramentas de marshalling XML lidem com versionamento de maneira mais sofisticada. Mas, que eu fico com um peh atras, eu fico.

  7. Tiago Albineli Motta 19/02/2008 at 14:20 #

    Prefiro a liberdade e leveza do JSON… Não gosto de elefantes.

  8. Fabio Kung 20/02/2008 at 00:07 #

    Não esquecendo do YAML e do HAML, na linha do JSON.

  9. Germano Fronza 20/02/2008 at 18:36 #

    Olá Paulo,
    Acho que aqui não é o local ideal para falar sobre isso,
    mas o VRaptor hoje trabalha só com JSON? ou já tem a possibilidade de utilizar WSDL/SOAP ou outros?
    Muito bom o post!! obrigado.

  10. Antonio Kantek 20/02/2008 at 19:25 #

    Mate o pequeno XML que existe dentro de voce.

  11. Christiano Milfont 21/02/2008 at 08:42 #

    @Felipe Gaucho

    “Ponto negativo: induz os novatos a enxergarem o REST e o JSON como o santo graal”

    Apesar que ele não induziu, isso seria o correto, REST já matou o WS-* faz tempo. Poucos player da WEB2.0 se dá ao luxo de não ter seus serviços como REST apesar de que não é apenas JSON.

    WS-* é para empresas “Enterprisey” chatas e burocráticas.
    REST é para startups jovens e bacanas.
    Que lado você está? 🙂

  12. Felipe 03/12/2009 at 23:11 #

    Acho que a questão de passar ou não o xml como uma string dentro do SOAP é uma questão que varia muito de tecnologia para tecnologia. Sou programador PHP e acho que me enquadro no perfil de desenvolvedor daquelas aplicações webservice mais antigas (aquelas que não fazem sentido… ou será que eram elas que faziam sentido?), mas gostaria de lembrar que o mundo de cliques e ferramentas para gerar os stubs e facilitar a vida do programador ainda não esta assim tão presente para os desenvolvedores PHP quanto esta para o Java e talvez seja por isso qua ainda existam as velharias por aí. E vamos deixar claro que aqueles servers antigos ainda estão cumprindo o seu papel, e em muitos casos de forma mais segura que os modernos. Mas vou deixar de ser ranzinza um pouco e dar os parabéns pelo belo post que tem bastante coisa interessante… basta saber filtrar. Mas deixo uma última frase pra reflexão: fazer um parser não mata ninguém, na verdade o que mata é a preguiça e a comodidade.

  13. Guilherme Silveira 09/12/2009 at 13:56 #

    Como o Ferreira comentou, a evolução de sistemas e o baixo acoplamento é fundamental quando se pensa em arquiteturas a serem mantidas a longo prazo: 2, 3, 5, 10 anos.
    Ficar publicando novos endpoints (como a Amazon faz) no estilo Corba é o servidor rebolando para fazer a coisa funcionar e mantem o atrelamento do cliente ao esquema antigo por um determinado período de tempo.

    A questão não é mudar somente para outro formato de representação de dados como JSON ou YAML, mas sim como as ferramentas do lado do servidor e do cliente interpretam essa sua represetanção de dados, como o Ferreira comenta.

    Interpretar JSON assumindo a não evolução de sistemas ou end-points fixos ainda matem um acoplamento mais alto do que seguir padrões ligados a Must-ignore e HATEOAS.

  14. juniorsatanas 29/08/2012 at 03:40 #

    Ele foi criado em 2000 através de uma tese de doutorado do Roy Fielding. Que por sinal é um dos criadores do protocolo http. Não bastasse o cara criou o REST.

    Se do outro lado tiver um Android, ai fica otimo !

  15. Max Hoo 17/09/2012 at 15:49 #

    Então.. aproveitar e fazer um pergunta sobre WebServises, Soa, etc..
    hoje tenho várias aplicações legadas e foi utilizado Axis 1.0 para gerar os WS (Soap 1.1, RPC/Encoded). E atualmente existem aplicações novas (java ee6) que vão consumir esses serviços. O que devo fazer? inserir as bibliotecas do Axis 1 dentro das minhas novas aplicações? ou criar um novo WSDL respeitando os padrões novos do (Document/literal) e disponibilizar uma nova versão desse serviço no barramento?
    muito obrigado.

  16. Luiz Henrique 24/01/2013 at 14:22 #

    Fala Paulo , mais uma vez muito bom o artigo.
    Cara tenho umaduvida , é tão “horrível” usar um Json como retorno de um webservice quanto devolver um XML ? Sei que o mais correto seria utilizar direto JSON via REST porém no cenário que temos hoje o nosso cliente não tem tempo hábil para implementar a solução utilizando REST. Eles demoram uma média de 15s para transformar o retorno do serviço em JSON, essa semana tive a idéia de devolver direto o JSON , porem direto do SOAP , não foi implementado ainda , estou estudando a alguns dias documentações e etc para ver se não é Gambiarra. Qual sua opnião a respeito disso. Vlw

Deixe uma resposta