Concrete Logo
Hamburger button

Retrofit 2: O que devemos saber

  • Blog
  • 12 de Julho de 2016

Retrofit é uma das mais poderosas e populares bibliotecas de HTTP Client para Android e Java, produzida pela Square Inc. e lançada como open source para toda comunidade.

Um dos princípios do Retrofit é a simplicidade, que permite que não nos preocupemos com toda a complexidade de criar uma conexão Web Service, uma vez que grande parte de sua correspondente lógica é abstraída. Com toda essa proposta, devemos apenas implementar algumas interfaces, anotar alguns métodos e voilà.

1

Neste post, vou mostrar um guia sobre a nova atualização desta incrível lib. Vou usar exemplos baseados em um projetinho que fiz consumindo a API do Dribbble, se interessar, está disponível no meu Github.

1. Novo conceito de URL

Na versão 1.x do Retrofit, caso quiséssemos consumir rotas de uma determinada API bastava setarmos um endpoint e sua correspondente rota que eles seriam concatenados em um path URL final. Olha só como era:

Agora na versão 2.x:

Percebeu a diferença?

4

Na versão 1.x, conforme mencionado anteriormente, o endpoint é concatenado diretamente com sua rota parcial. Já na versão 2.x, deve-se prestar muita atenção, pois a “Base Url” não é concatenada com sua rota parcial. Você pode perceber que o “v1” será sobrescrito por “/” no início da rota parcial (“/shots”). Isto acontece porque a nova versão do Retrofit usa o método HttpUrl.resolve() para criação da URL final. Este método gera um link similar ao modelo <a href>. Vamos ver como deveríamos consumir uma API, respeitando o novo conceito:

Como podemos ver acima, conseguimos o resultado final conforme esperávamos. Uma boa dica é usar “/” ao final da base url e não ter a contrabarra no início de uma rota parcial.

Aproveitando o assunto, vale destacar uma feature complementar que veio para salvar nossas vidas. Antes de explicá-la, vamos voltar à versão 1.x.

Anteriormente, se quiséssemos acessar uma URL diferente por algum motivo (como coletar algum tipo de informação, por exemplo) deveríamos criar outra estrutura de RestAdapter, algo trabalhoso e bastante árduo.

O novo conceito de URL implementado pelo Retrofit nos possibilita inserir dinamicamente outras URLs, podendo passar diretamente pelo campo da anotação de HTTP verb ou simplesmente deixá-lo vazio e passar a anotação @URL dentro do método a ser implementado. O Retrofit vai fazer todo o tratamento debaixo dos panos. Vejamos exemplos:

2. OkHttp

Nas versões 1.x do Retrofit, podíamos setar qualquer HTTP Client que quiséssemos. No Retrofit 2, porém, o OkHttp já vem incluso em sua própria dependência. Isso porque é o OkHttp quem fornece a classe Call (falaremos um pouco mais sobre isso), e por isso sua inclusão é necessária.

2.1. Interceptors

Assim como no Retrofit 1, na versão 2.x caso queiramos customizar nossas requisições, como adicionar um header ou um log, por exemplo, precisamos sobrescrever o OkHttpClient e adicionar um Interceptor. Após toda a configuração, devemos passar nosso HTTP Client customizado ao método “.client()” do Retrofit, que substituirá o default. Vejamos um exemplo:

Como disse anteriormente, caso quiséssemos adicionar um log em nossas requisições, bastava adicionar um interceptor. Pois bem, e se você soubesse da triste notícia de que não há mais logging?

7

E agora?? =(

O time de desenvolvimento do Retrofit realmente removeu esta feature. Porém, desenvolvedores do OkHttp lançaram separadamente um tipo Http logging, que pode ser adicionado ao seu projeto de uma maneira bem simples: basta adicionar sua dependência e um novo interceptor. Fica assim:

Obs: é recomendado adicionar logging como último interceptor, pois ele pode “loggar” suas informações de interceptors de requests anteriores.

11

3. Converters

Nas versões anteriores ao Retrofit 2, um Json Converter vinha incluso como padrão, o Gson. Agora, ele não vem mais integrado por padrão, deve-se definir como uma dependência à parte.

No exemplo, eu usei um converter para a biblioteca LoganSquare, mas existem outros listados no próprio site do RetrofitVocê também pode criar seu próprio converter, basta herdar a classe “Converter.Factory”. Após incluir a dependência, basta adicionar na construção da instância do Retrofit.

4. Requests

Conhecendo um pouco sobre a versão 1.x, sabemos que para definir um método de característica síncrona deveríamos criar um método com tipo de retorno. Em contrapartida, um método de característica assíncrona era void e recebia como último parâmetro um CallBack para a resposta do corpo da requisição.

Agora, não existe uma distinção de métodos para uma requisição síncrona ou assíncrona.

Lembra que mencionei no começo sobre o porquê de o OkHttp já vir incluso no Retrofit? Então, precisamos ter esta outra biblioteca adicionada porque ela trabalha com a classe Call, que simplifica a declaração do tipo de resposta das requisições. Basta adicionar “call.execute” para um request síncrono e “call.enqueue(…)” para um request assíncrono. Exemplo de um request síncrono:

Exemplo de uma requisição assíncrona:

Não podemos deixar de lembrar que o método “onResponse” não é chamado apenas quando vier uma resposta de sucesso do servidor. Em contrapartida, caso dispare em uma requisição assíncrona um “IOException”, será chamado no “onFailure”, indicando que houve um erro de rede, tal como socket timeout, uknown host, etc.

Portanto, é preciso tomar cuidado ao tratar as requisições de sua aplicação, pois comportamentos inesperados poderão aparecer caso não haja essa precaução de tratamento. Para que a classe CallBack satisfaça o resultado esperado para tratamentos eventuais de erro, uma dica seria criar uma classe customizada, que estenderia a classe CallBack ao invés de retornar apenas “onResponse(…)” e “onFailure(…)”. Assim, você poderia tratar conforme o seu desejo.

4.1. Cancelar Requests

Vamos imaginar que queremos fazer uma requisição que, por algum motivo, demore para ser finalizada e, cansado, o usuário não quer esperar o término do request, ele quer cancelar. Como faríamos?

Calma… No Retrofit 2, isso pode ser feito de uma forma muito simples e objetiva. Basta usar “call.cancel()”. Ficaria assim:

Devemos prestar atenção em um ponto: após o cancelamento da requisição, o Retrofit vai classificar essa operação como uma falha de rede, se encaixando no parâmetro de tratamento do “onFailure”.

Como falamos anteriormente, o “onFailure” também recebe erros de rede, logo, é preciso diferenciar se houve de fato o disparo do cancelamento da requisição ou um erro de conexão de Internet.

Para salvar nossas vidas (mais uma vez), podemos fazer essa verificação apenas usando o que a classe Call nos oferece, um booleano “call.isCancelled()”.

5. Conclusão

Abordamos aqui algumas comparações, dicas e principais mudanças que são essenciais para termos em mente, mas existem outras que você pode conferir melhor no Change Log do Retrofit, principalmente se gosta de acompanhar com mais detalhes cada lançamento feito.

Espero ter ajudado! Caso tenha alguma dúvida ou algum ponto a acrescentar no assunto abordado, sinta-se à vontade para deixar seu comentário logo abaixo. Até a próxima!

É desenvolvedor e quer fazer parte do nosso time? Acesse aqui.