Categories
Fun REST Ruby

Cadê meu Sedex?

Quem usa o serviço de Sedex e encomendas dos Correios sabe como é um saco entrar no site dos Correios para saber onde está sua encomenda. Como eu vendo e compro bastante coisa no Mercado Livre, há alguns anos desenvolvi um widget para Mac OS X que facilita buscar essas informações, mas acabei não usando muito porque não era prático o suficiente.

Na sexta-feira passada conversando com uns amigos tive a idéia de fazer um brincadeira no Twitter que poderia ser uma solução suficientemente prática: você digita no Twitter @cade_meu_sedex SO376590583BR” (usando o número da sua encomenda ao invés do meu, obviamente) e o macaco dos Correios diz pra você qual é o status mais recente disponível no site dos Correios. 🙂

cade_meu_sedex

Fazendo essa brincadeira acabei desenvolvendo uma API Ruby e de webservices REST para consulta ao site dos correios, que foi batizada com o misterioso nome de “correios-api”. Essa API já está disponível como uma RubyGem e no site do projeto tem instruções para instalação e uso.

Tanto o robô quanto a API foram desenvolvidos em Ruby e os códigos estão no meu Github para quem quiser dar uma olhada. No caso dos webservices foi especialmente ridículos fazê-los usando o Sinatra, que é um framework sensacional e absurdamente simples.

A próxima feature desse projeto será criar métodos para fazer orçamento de encomendas, que foi uma idéia dada pelo pessoal da lista Rails-BR. Se alguém tiver outras idéias ou quiser colaborar seja bem-vindo!

Categories
REST SOAP Webservices

A guerra entre REST e WS-* acabou!

Acabo de ler um artigo no InfoQ entitulado The REST versus WS-* war is over!.

Só que pra ser bem sincero eu não concordo muito com este artigo. Para mim essa guerra nunca existiu.

Veja bem, é mais ou menos como tentar fazer uma guerra entre facas de pão e facas de peixe para tentar descobrir qual é a melhor. Oras, se você está comendo peixe, a melhor faca é a faca de peixe. Se você vai cortar um pão, a melhor faca é a de pão. Tá bom, essa analogia foi ridícula, mas é tão ridícula quanto uma comparação entre REST e WS-*/SOAP.

O que eu quero dizer é que, assim como funciona com as facas, o tipo de webservice que se usa varia em função do cenário de uso.

Nem todos os tipos de sistemas precisam da quantidade de recursos que WS-*/SOAP oferecem e isso torna-se um overhead desnecessário. Por exemplo, é muito mais fácil fazer mashups e sites com vários recursos Ajax utilizando webservices REST. Em compensação você pode precisar fazer orquestrações de webservices, operações transacionais, roteamento e outras coisas que REST não oferece mas que com WS-*/SOAP se faz com relativa facilidade.

Certamente há espaço para os dois no mercado, não vejo motivos para encararmos como uma guerra.

Categories
REST Webservices

POST vs. PUT: quem insere e quem altera?

Eu e o Phillip Calçado estamos trabalhando numa aplicação com uma interface de webservices REST.

Um dos pontos que estavamos discutindo hoje é sobre os métodos POST e PUT. Qual deles que representa um INSERT e qual representa um UPDATE? Se você procurar na internet vai perceber que vários sites dizem várias coisas diferentes. Foi quando resolvemos mergulhar no problema e entender qual é a forma correta de se fazer as coisas.

Superficialmente falando, webservices REST são CRUDs (acrônimo para Create, Read, Update e Delete). Por isso é muito natural tentar traçar um paralelo entre os métodos HTTP e as operações de banco de dados feitas por um CRUD

HTTP -> SQL

  • GET -> SELECT
  • DELETE -> DELETE
  • POST -> UPDATE
  • PUT -> INSERT

O nosso erro foi justamente esse de tentar traçar um paralelo com as ações de um CRUD. Se você pensar em SQL, realmente faz sentido que o POST seja um UPDATE e o PUT um INSERT. Porém quando se trata de webservices REST a coisa fica um pouco diferente porque HTTP é um pouco diferente de SQL.

O funcionamento do método PUT é “colocar” uma página numa determinada URL. Se a página já existir naquela URL ela é substituída. Se não houver página, ela é criada e passa a ser a que foi enviada no PUT. PUT é uma operação limitada que simplesmente coloca uma página numa localidade. Além disso, PUT é idempotente, ou seja, se você fizer 20 vezes um PUT numa URL o resultado tem que ser o mesmo que seria se você fizesse uma vez só: é o mesmo que acontece se você executar 20 UPDATES em um registro, é o mesmo que executar um update só.

Para exemplificar, considere que estamos criando um usuário num sistema qualquer. Neste sistema, a URL para obter (GET) um usuário de ID 1, por exemplo, seria:

http://gc.blog.br/usuarios/1

Então, se você desejasse criar um usuário utilizando PUT, a URL teria que ser:

http://gc.blog.br/usuarios/[id]

Porém quando você cria um objeto você normalmente não sabe qual é a chave primária/id deste objeto. Quem te dá esta informação é o sistema, não é você que escolhe. Neste caso, se você fizer um PUT numa URL de um usuário que já existe, você o AUTALIZARIA ao invés de criar um usuário novo.

Para criar um usuário o correto seria fazer um POST para a URL:

http://gc.blog.br/usuarios

Ao receber um POST esta URL cria um novo usuário e retorna o ID dele no response. O POST não é idempotente e se esta URL for chamada 20 vezes, 20 usuários serão criados e cada um deles terá um ID diferente: o mesmo que acontece quando você executa 20 INSERTS. Esta URL pode ser considerada como uma Factory de objetos Usuario.

Sendo assim a forma correta de se mapear os métodos HTTP para ações de um CRUD é:

  • GET -> SELECT
  • DELETE -> DELETE
  • POST -> INSERT
  • PUT -> UPDATE

Em alguns casos, porém, você sabe qual é a URL que será criada para o usuário. Por exemplo, os seus usuários poderiam ser representados da seguinte forma:

http://gc.blog.br/usuarios/guilherme

Ou seja, para criar um usuário com PUT você poderia chamar uma URL com o padrão:

http://gc.blog.br/usuarios/[login]

Porém esta operação é extremamente arriscada. Se já existir um usuário “guilherme” o sistema achará que você está tentando atualizar o Guilherme ao invés de criar um novo e o “guilherme” antigo irá se perder. Se for um POST o sistema pode retornar uma mensagem dizendo que não pôde criar o “guilherme” porque já existe um usuário com este login.

Categories
Notícias REST Webservices

IDLs para REST

Ultimamente têm se discutido muito se webservices REST precisam ou não de uma IDL (Interface Description Language) que seria mais ou menos o que o WSDL é para webservices SOAP.

Enquanto a discussão rola, alguns já começaram a desenvolver soluções, como é o caso de Thomas Steiner que lançou a versão 0.3 da sua ferramenta REST Describe & Compile tool.

Para ver que tipo de saída é gerada pela ferramenta, você pode testar a versão online do REST describe. Caso você não tenha uma URL para testar, use algum dos webservices da Last.fm (Audioscrobbler) como este que obtém os 50 artistas que eu mais ouço: http://ws.audioscrobbler.com/1.0/user/gchapiewski/topartists.xml.