Precisamos de um descritor de serviços REST?

maio 14, 2008

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! 🙂

Anúncios

Atom: one format to rule them all?

março 3, 2008

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

Recently I’ve had several conversations regarding the Atom Syndication Format. This format is gaining more and more adopters and several big players in the industry are using it. Just to name the big boys, Google AND Microsoft are using it to implement RESTful APIs. When was the last time you heard Google and Microsoft agreed on something? 🙂 This should hint that Atom is indeed a nice thing happening in our field.

Web services using the Atom format for data exchange encapsulate information using Atom’s standard elements and also define some extension points where needed. Some very useful elements are present in the specification. There are standard ways of publishing individual entries and collections, pagination support, links between resources, among other things useful for RESTful web services.

Depending on your domain model, the amount of data you would put in Atom extension points varies a lot. Some domains such as Google Apps can produce a RESTful model that uses a lot of Atom’s standard elements without needing to define too much extension points. However, if you use Atom to exchange billing information between ISP applications, you’ll probably have to define a lot of extension points. I’m saying this to show that some domains match much better to Atom structures than others.

While talking to Silvano (a very clever working mate of mine) a couple of weeks ago, he asked me if encapsulating everything inside Atom elements was not the same as encapsulating everything inside SOAP. This is a very very good question.

When you’re choosing a format for you data exchange in web services, it’s very important to analyse what you gain and what you lose by picking any given format.

For example, a good rule of thumb about SOAP services is: “WS-* is just overhead unless you have something meaningful in your SOAP Headers” (quoting Sanjiva Weerawarana at ApacheCon 2007).

Atom was designed in a RESTful manner by a very talented group of professionals. Many applications are making use of it to exchange data, and the adoption is growing fast. Could it be a silver bullet then?

That’s where I shall leave my observations. If you consider my example of billing information, you’ll see that most of the data there doesn’t mesh well with Atom’s standard elements. Thus, we’d need to define a lot of extension points, and wouldn’t make much use of Atom’s resources. Putting billing data inside Atom entries would represent an overhead without giving us much in return. In this case, I’d rather use my own XMLs directly over HTTP.

Am I saying that Google and Microsoft made a bad decision choosing Atom? No, absolutely not! Their decision was very good. Microsoft is using Atom for Windows Live API and Google’s using it for most of their applications. What do these have in common? They all manipulate web content. They have a domain where many things are accessible on the web, with lots of URIs, different media types, pagination, categories, tags, etc. Atom makes a lot of sense with web content.

I don’t think Atom is a Silver Bullet for RESTful web services in general. Of course you can choose to always use it, and benefit from the standards and the avaiable tools. But isn’t this true for SOAP as well?

What I do think is that Atom is very close to a Silver Bullet when you’re dealing with web content. Whenever you’re developing web services, choosing the right format for your data exchange is one of the most important decisions. To know well the avaiable options is very helpful, and certainly the Atom format brings a lot to the table when your domain meshes well with it. As long as you don’t think it’s the best choice for every application, go ahead and use it wisely 😉