Por muito tempo eu vinha utilizando a forma tradicional de consumir APIs em Ruby: através da biblioteca Net::HTTP. Era bastante prático e até então simples. Não precisava adicionar nenhuma nova gem ao meu projeto e a documentação é bastante vasta.
Até que um dia fui apresentado ao Unirest, que torna o trabalho de acesso às APIs especialmente muito mais trivial e sem grandes alterações na configuração quando estamos tentando acessar recursos protegidos com SSL e outros não.
Aqui vão algumas dicas que me fez adicionar esta GEM em praticamente todos os projetos que trabalho quando é necessário o acesso a URLs externas.
Instalação
Apenas uma gem, sem grandes dependências:
gem install unirest
Mecânica
A forma básica de utilizar o Unirest é:
response = Unirest.MÉTODO(URL, HEADERS, PARAMETROS, AUTENTICACAO, CALLBACK)
Onde:
- MÉTODO: um dos verbos http: get, post, delete, put e patch;
- URL: a URL do serviço a ser acessado;
- HEADERS, PARAMETROS e AUTENTICACAO: um objeto Hash (chave:valor) com os respectivos valores para cada finalidade (header, parametro e autenticação).
Como resposta, a chamada do MÉTODO é possível obter:
- response.code: código de resposta do HTTP, 200 significa que não houve erros no processamento;
- response.headers: header da resposta do servidor;
- response.body: conteúdo da resposta. Geralmente é isso que nos interessa saber;
- response.body_raw: conteúdo sem formatação da resposta.
Exemplos de utilização
A forma de envio de um request, seja GET, POST, DELETE ou PUT é exatamente o mesmo. Basta alterar o MÉTODO:
Uma chamada GET ao serviço de clima da Open Weather Map pode ser disparado através do seu browser: http://api.openweathermap.org/data/2.5/weather?q=São Paulo.
Mas também pode ser escrita utilizando o Unirest da seguinte forma:
response = Unirest.get("http://api.openweathermap.org/data/2.5/weather", parameters:{:q => "São Paulo"})
Autenticação
Algum tempo atrás eu mostrei como utilizar Basic Authentication para proteger sua aplicação Rails. Se nesta mesma aplicação os serviços estiverem protegidos com a basic authentication, através do Unirest é muito fácil de serem acessados; basta utilizar o parametro auth.
response = Unirest.get("http://localhost:3000", auth:{:user => "usuario", :password => "senha"})
Upload de arquivos
Algumas APIs permitem que você atualize sua foto do perfil, ou na publicação de algum anúncio faça o upload de imagens do seu produto. Esta é a forma como esta tarefa pode ser feita com o Unirest:
response = Unirest.post("http://httpbin.org/post", headers:{"Accept" => "application/json"}, parameters:{:file => File.new("/temp/arquivo", "txt")})
Request assíncrono
Por alguns motivos, pode ser necessário que seja feito um artigo para determinado serviço, mas a sua resposta não seja de fato necessária. Ou ainda que seja necessário, em caso de falha, apenas um log dessa falha. Com o Unirest é possível fazer chamadas assíncronas sem que o usuário final seja impactado no tempo de resposta.
response = Unirest.post("http://httpbin.org/post", headers:{"Accept" => "application/json"}, parameters:{:nome => "Meu nome"}) do |response| puts "response.code: #{response.code}" puts "response.body: #{response.body}" end
Timeout
É possível configurar um timeout para as chamadas aos serviços externos através do método : timeout(n)
Unirest.timeout(10) #configura o timeout para 10 segundos
Headers padrão
Assim como é possível definir um timeout padrão para todas as chamadas, também é possível definir algumas entradas de headers para todas as chamadas externas:
Unirest.default_header('chave1', 'valor1')
Essa definição evita, caso você tenha uma chave padrão no header que deva ser enviada a cada request, que seu código fique muito verboso.
Ainda é possível limpar todas as entradas no header com o comando:
Unirest.clear_default_headers()
Tendo a configuração de timeout quanto a default_header, sempre que possível eu as deixo como inicialização do meu projeto.
Conclusão
A biblioteca padrão Net::HTTP é bastante poderosa, mas também um pouco complicada de configurar. O Unirest é uma alternativa de simples utilização. E caso você não tenha restrições quando a utilizações de novas gems em seu projeto, pode ser uma escolha bastante acertada.
O Unirest ainda tem versões para Java, Python, .Net, Objective-C, Node e PHP.