Consumir informações da internet sempre foi algo essencial, e no mundo de desenvolvimento mobile então é algo quase que mandatório. Aplicações que possuem grande valor são aquelas que tem a capacidade de se comunicar com sistemas heterogênios e acessar informações para apresentar em alguma camada de apresentação para os usuários.
Muitos aplicativos que usamos no dia a dia faz do uso de consumo de informações como algo central, aplicativos como Instagram, Facebook e Twitter usam uma arquitetura de consumo de informações quase que universal. Primeiro consultam um banco de dados remoto para verificar se existe alguma informação relevante para ser apresentado ao usuário, como novos Tweets, ou novas fotos para o feed do Instagram. De forma geral, esse processo de comunicação acontece nos dia de hoje em sua maioria por uma API Rest.
Porque uma API REST?
Como podemos ver na imagem acima, uma API ou (Application Programming Interface para os íntimos) é o ponto de encontro de diferentes plataformas para consumo de informações remotas, e em outras palavras uma API permite com que independentemente da linguagem ou da plataforma possamos nos comunicar com serviços e ou códigos de terceiros.
Mas o que significa REST no nome?
REST ou (Representational State Transfer) é uma tecnologia construída em cima dos protocolos de comunicação HTTP, com ela podemos usar os verbos (GET, POST, DELETE ou PUT) para ler, alterar ou deletar informações em uma fonte remota. Em programação, com frequência chamamos tais verbos de CRUD que do Inglês possuem o mesmo significado (Create, Read, Update or Delete).
Por debaixo dos panos, quando queremos usar uma API REST para ler (READ) informações de um banco de dados remoto, usamos a API que faz com que nossa requisição seja interpretada, e executada no banco de dados, os resultados são retornados pelo protocolo HTTP.
Dessa forma, nossa principal responsabilidade como desenvolvedor é montar uma requisição apropriada para consultar o banco de dados, e ao final interpretar os resultados para apresentar ao usuário por meio de alguma interface gráfica UI todas as informações retornadas pela consulta.
Exemplos de uma API REST
Para ler informações de uma fonte remota, conforme já citado em parágrafos anteriores temos que disparar uma requisição GET e para tal devemos aponta-la para um endpoint apropriado. Um endpoint é apenas um caminho personalizado da API que interpreta requisições e faz a busca apropriada em uma parte específica do banco de dados.
Ex: (GET http://www.alifyz.com/usuarios)
Na requisição acima, estamos disparando uma requisição GET para o caminho /usuarios que tem como principal objetivo ler informações sobre os usuários da fonte remota. Da mesma forma podemos consultar outras partes do banco de dados remoto ao disparar a mesma requisição para um endpoint diferente, como os a seguir: ../posts, ../dados e etc.
Se quisermos criar um registro ao invés de ler informaçõies podemos criar uma requisição e adicionar uma informação no banco de dados remoto usando o verbo HTTP @POST.
Ex: (POST http://www.alifyz.com/usuarios)
No contexto acima, precisamos enviar informações por meio da API, e o principal método é construir uma requisição POST e colocar as informações dentro do Body (corpo) da requisição. Então sempre que você estiver postando algo na Internet, uma requisição POST está sendo construída e as informações que você criou estarão dentro do Body da requisição.
Como o principal foco deste artigo é falar sobre consumir informações (GET), deixamos os demais métodos PUT e DELETE para uma segunda parte.
Ferramentas necessárias
Para este artigo, iremos usar duas das mais utilizadas bibliotecas para consumo de APIs no Android.
Retrofit é uma biblioteca open-source para consumo de APIs e para Networking de forma geral, com ela podemos criar requisições e utilizar nossa aplicação como um Client HTTP de forma rápida e simplificada. Contudo, ainda precisamos transformar as informações retornadas pela API em algo útil, para isso iremos utilizar o Gson como principal ferramenta para transformar a resposta do Servidor em um objeto que possamos manipular. Este processo também é conhecido como deserializar ou serializar informações em objetos.
Iniciando o projeto
Crie um novo projeto com o Android Studio e adicione as seguintes dependencias no gradle a nível de aplicativo
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
Com as nossas dependencias no projeto, vamos criar uma classe auxiliar em Kotlin para configurar uma instância do Retrofit e definir os endpoints necessários para nossa consulta.
Edit: (Além das configurações acima, também precisamos adicionar a permissão para acesso a Internet no
AndroidManifest.xml)<uses-permission android:name="android.permission.INTERNET"/>
Dê o nome que desejar, mas em meu exemplo decidi implementar essa nova classe auxiliar com um nome mais sugestivo para os demais e talvez futuros desenvolvedores envolvidos. NetworkUtils.kt
class NetworkUtils {
companion object {
/** Retorna uma Instância do Client Retrofit para Requisições
* @param path Caminho Principal da API
*/
fun getRetrofitInstance(path : String) : Retrofit {
return Retrofit.Builder()
.baseUrl(path)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}
}
No código acima, nossa função getRetrofitInstance precisa de um caminho principal para a API, ex (http://www.alifyz.com/) ou (http://www.suaapiaqui.com.br/) dessa forma podemos reutilizar a mesma função para disparar requisições para caminhos diferentes, e ainda não precisar informar a URL básica sempre que disparar uma nova requisição. Afinal, apenas algumas características da URL costuman mudar.
Ao adicionar o Gson como converterFactory estamos criando a capacidade do Cliente HTTP do Retrofit de converter as informações retornadas pela API em um objeto que contenha as mesmas informações e assim ter a capacidade de manipular e usar como quisermos em nossas aplicações.
Configurando o Layout e Endpoints
Agora vamos configurar nosso Layout para apresentar as informações que virão de uma Fake API conhecida como JSONPlaceHolder com este site podemos testar nosso Cliente HTTP e realizar requisições GET, POST, PUT e DELETE.
A Plataforma JSONPlaceHolder contém os seguintes endpoints que podemos usar para testar nosso Cliente HTTP.
Em sua maioria, quando disparamos uma requisição recebemos em troca uma lista de informações, dessa forma fica fora do escopo deste artigo implementar de acordo com a documentação Listas e Adaptadores como ListView e RecyclerView.
Em nossa Activity Principal, vamos apenas inserir um Textview simples que irá receber todo o conteúdo da API.
O Layout principal ficou da seguinte forma:
Configurando o Endpoint
Vamos adicionar os endpoints necessários para consumir os dados da API utilizando uma Interface, assim delegamos a responsabilidade por implementar os verbos HTTP para a biblioteca Retrofit e nos preocupamos apenas em tratar as respostas.
Antes de implementarmos a Interface que será utilizada pelo Retrofit ao consumir as informações, precisamos analisar e criar uma classe que irá representar a resposta que contém as informações retornadas pela API, para isso precisamos criar uma classe com os atributos e padrões necessários para que o GsonFactory converta as respostas em objetos que possam ser úteis para nossa aplicação, ou seja precisamos de um Modelo ou (Model em Inglês)
Iremos disparar uma requisição GET no seguinte endpoint (https://jsonplaceholder.typicode.com/posts)
Que irá listar uma série de posts, cada item da lista será composto por um objeto com os seguintes atributos.
- userId (number)
- id (number)
- title (string)
- body (string)
Para facilitar esse processo, podemos copiar o resultado apresentado no link acima, e usar o site jsonSchema2Pojo para criar um POJO que irá corresponder ao nosso modelo esperado. Quase sempre, o resultado retornado por uma API estará no formato json.
Veja como ficou o nosso modelo implementado em Kotlin:
data class Posts(
@SerializedName("userId")
var userId : Int,
@SerializedName("id")
var id : Int,
@SerializedName("title")
var title : String,
@SerializedName("body")
var body : String
)
Podemos usar a anotação @SerializedName para facilitar o processo de conversão e serialização, mas isso se torna desnecessário se os nomes das variáveis forem compatíveis e os tipos forem os mesmos.
Agora que já temos o nosso modelo, vamos configurar nossa Interface.
Com o código acima, estamos criando um endpoint que irá utilizar o verbo GET e irá retornar um objeto retrofit do tipo Call que será nosso container de uma lista de objetos do tipo Posts. Utilizamos o container do tipo Call para processar as requisições em uma Thread separada e de forma assincrona. Afinal, o tempo necessário para processar a requisição será imprevisível e não podemos travar a aplicação.
Disparando a Requisição
Após construir nossa classe de utilidades e configurar nosso endpoint, vamos finalmente disparar nossa requisição e extrair os dados da Lista e exibir em nosso TextView principal.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getData()
}
fun getData() {
val retrofitClient = NetworkUtils
.getRetrofitInstance("https://jsonplaceholder.typicode.com")
val endpoint = retrofitClient.create(Endpoint::class.java)
val callback = endpoint.getPosts()
callback.enqueue(object : Callback<List<Posts>> {
override fun onFailure(call: Call<List<Posts>>, t: Throwable) {
Toast.makeText(baseContext, t.message, Toast.LENGTH_SHORT).show()
}
override fun onResponse(call: Call<List<Posts>>, response: Response<List<Posts>>) {
response.body()?.forEach {
textView.text = textView.text.toString().plus(it.body)
}
}
})
}
}
A função getData é a responsável por consumir as informações da API fake que usamos. No exemplo acima, a variável retrofitClient faz uso da nossa função escrita na classe NetworkUtils, e em seguida precisamos criar as variáveis do tipo endpoint e Callback que serão utilizados para que o Retrofit possa montar a requisição.
Para realizar a requisição de fato precisamos chamar o método enqueue da variável callback, que irá processar as informações do endpoint e gerar uma requisição valida, e logo em seguida dependendo do resultado da requisição, o Retrofit poderá invocar os métodos onResponse caso o resultado seja posivivo, e onFailure caso o resultado seja negativo, e assim podemos exibir uma mensagem de alerta para o usuário o informando que houve problemas em consultar as informações.
Veja como ficou nosso Textview com a lista de informações fakes que a API retornou.
Em resumo, isso é tudo que precisamos para consumir informações do banco de dados com uma API e usando as biliotecas Retrofit e Gson. Espero que goste desse artigo e caso tenha dúvidas deixe sua pergunta na seção de comentários.
Happy Coding!
Deixe um comentário