Esta semana foi necessário integrar um sistema que estamos desenvolvendo com Python e Django ao sistema de cobrança F2B. Basicamente acessar os serviços como cliente, através de web services. Este artigo relata a experiência.
A única interface oferecida é SOAP (simple object access protocol). Outra maneira de utilizar os serviços é através de GET ou POST, mas diferente de um web service REST, neste caso seria necessário que nosso usuário fosse redirecionado à página da F2B, o que é indesejado.
Não tendo outra saída a não ser usar SOAP, uma pesquisa foi iniciada para descobrir bibliotecas em Python para este trabalho. Foram descobertas várias. Entre as open source, muitas estão descontinuadas ou sem suporte. As mais confiáveis e utilizadas são SOAPpy e ZSI.
A bilioteca ZSI é evolução da SOAPpy e pode-se dizer que ambas caminham para a unificação sobre o nome da primeira. Ambas podem ser encontradas no endereço http://pywebsvcs.sourceforge.net/.
As duas dependem da biblioteca pyXML, projeto que está atualmente descontinuado. Como o desenvolvimento está se dando em ambiente windows e Pyhton 2.5, houve dificuldade para encontrar esta biblioteca compilada. Em tentativas de compilação em ambiente windows, foi exigido o Visual Studio 2003, impedindo a continuação do processo. Em fim uma busca refinada no Google encontrou a biblioteca pyXML compilada para python 2.5 e win32, entretanto com um grande aviso “use por sua conta e risco”.
Depois de alguma luta, as bibliotecas instaladas, iniciaram-se os testes, tentando acessar um web service simples que fornece a temperatura de um local a partir do cep da área (estados unidos). Houve um problema com “namespaces” e não foi possível o acesso porque a biblioteca ZSI pelo que consta não tem suporte a namespaces, a não ser em casos onde o se tem acesso ao lado do servidor. Uma nova tentativa foi criando-se um pequeno web service a ser servido na porta 8080 e um cliente para acessa-lo. Pouco código, coisa simples. Mesmo assim por um motivo ainda não identificado não deu certo. As fontes de pesquisa foram um artigo no site da IBM e o material do Dive Into Python
Trabalho frustrante. Praticamente um dia inteiro, foco perdido do sistema e voltado para web services usando SOAP. Foi uma decepção encontrar tão pouco recurso para utilizar este protocolo no Python, que é de certa forma tido com “padrão” no que se trata de Web Services.
Fraquezas do SOAP
Padrão SOAP? Entre aspas… Há um grande grupo de desenvolvedores que acreditam que a tecnologia de web services, que se diz simples e de fraco acoplamento, está “metendo os pés pelas mãos” quando adota SOAP como padrão.
Web services com SOAP funcionam da seguinte maneira: Você cria uma classe, e utiliza alguma biblioteca para torná-la acessível pela internet. Junto cria um arquivo chamado WSDL(Web Services Definition Language) que é uma descrição dos métodos públicos oferecidos por seu serviço e de como acessa-los, no formato XML. O cliente por sua vez, através da WSDL, acessa o serviço enviando a requisição como um arquivo XML e recebe a resposta também como um XML, segundo as regras definidas no arquivo WSDL do serviço. A idéia é que através da WSDL o sistema seja capaz de entender o web service e interagir com ele.
Em conceito está perfeito, entretanto a prática é um pouco diferente. A WSDL é fortemente “tipada”, ou seja, tem tipos de variáveis inflexíveis. Se tratando de uma tecnologia que pretende acoplar outras tecnologias para que trabalhem juntas, de forma distribuída, este já é um entrave. Os tipos variam entre as linguagens e a WSDL pretende criar tipos que são comuns a todas, e este é o ponto crítico. SOAP torna o acoplamento forte, pois se o criador do web service alterar poucos pontos do arquivo WSDL já é o suficiente para quebrar os sistemas clientes.
Além disso, o dialeto XML que compõe a WSDL faz com que seja obrigatório o uso de uma biblioteca para facilitar seu processamento e criação, pois escrever WSDL “na mão” é cansativo e sujeito a falhas, tornando assim o desenvolvedor dependente de uma (ou mais) ferramentas.
O método REST
Uma alternativa mais simples e de fraco acoplamento é o método REST . Chega a ser simples demais descrever este método de acesso à web services, mas é na simplicidade que está sua força.
REST é a sigla para Representational State Transfer. A internet por natureza é um meio de acesso a recursos, e não serviços, e REST segue esta filosofia. Para acessar um web service pelo método REST basta que se conheça sua URI e passe parâmetros usando métodos do protocolo HTTP, sendo eles GET, POST, PUT ou DELETE. O protocolo usado é HTTP, da mesma forma que se acessa uma página web qualquer. Ao acessar a URI informando dados, o web service retorna como resposta os dados solicitados, no formato que o criador do serviço bem entender. Cabe ao desenvolvedor estabelecer padrões, caso ache necessário.
Como no fim, para trafegar na web, qualquer tipo de variável é convertida em string, o método REST não se prende a tipos de variáveis, o que o torna de fraco acoplamento, seguindo os conceitos inicias dos web services. No destino, o desenvolvedor pode, a partir da string recebida, converter no tipo que precisar. Praticamente todas as linguagens de programação oferecem recursos para transforma string em tipos específicos.
O acesso através de simples requisições HTTP torna o serviço acessível a todos, sem a necessidade de que se gaste tempo (precioso) aprendendo WSDL, UBBI ou outra sigla estranha. REST se enquadra no conceito que se prova cada vez mais verdadeiro em desenvolvimento de software, que diz que “fazer menos é fazer mais”. Menos software, menos regras, menos falhas, mais qualidade, mais prazer em trabalhar.
Conclusão
Como “prazer” e “fazer da forma mais simples” é mola mestra de quem opta por Python, já está explicado porque se tem pouco suporte a SOAP na linguagem. Mesmo assim, há casos, como este, nos quais não há escolha, é obrigatório se adequar ao SOAP. A biblioteca ZSI cumpre bem este papel, apesar da curva de aprendizagem um pouco maior comparada a quem acessa um web service REST, usando a “urllib”, biblioteca padrão do Python. Mas este é um defeito do SOAP, não do Python.
A Amazon oferece seus web services nos dois modelos, REST e SOAP. REST tem 70% mais aceitação. A simplicidade no acesso popularizou estes serviços e vem se mostrando um padrão “na prática”. Entretanto vemos cursos de informática com professores ensinando SOAP e frizando que “SOAP é o padrão de mercado e deve ser seguido”. Fica a nota aos desenvolvedores que estão criando web services, e o lamento pela necessidade de ter que perder horas tentando “temperar” esta SOAP para que funcione corretamente.
Leituras sugeridas