Como Implementar Retrofit en nuestra App
Tags: spanish, programming, tutorial
Published: 2022-12-07 13:56:20

Retrofit es una de las mejores librerías para implementar llamados de APIs en nuestras apps en Android. Hoy explicaremos como implementar un llamado a la API de Pokemon: [PokeAPI](https://pokeapi.co/).

Antes que nada, debemos instalar las dependencias necesarias para usar esta librería en nuestro build.gradle del modulo app:

```gradle
implementation 'com.google.code.gson:gson:2.7'
implementation 'com.squareup.retrofit2:retrofit:2.1.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
```
Gson es un parser que convertirá el json que nos devuelve la API en objetos Java que nosotros definamos como modelos.

Luego debemos crear una interfaz que le permitirá a Retrofit saber los endpoints que se usarán en la app. Por ejemplo, usaremos el endpoint para obtener la información de un Pokemon, el cual es [https://pokeapi.co/api/v2/pokemon/ditto/](https://pokeapi.co/api/v2/pokemon/ditto/). Entonces debemos dividir dicha URL en dos partes:

- URL Base: https://pokeapi.co/api/v2/
- Endpoint: pokemon/ditto/

Ahora vamos a crear la Interfaz:

```java
public interface PokemonAPI {
    @GET("pokemon/{id}")
    Call<PokemonByIdResponse> getPokemonById(@Path("id") String id);
}
```

Vamos a ver este snippet por partes:

- El annotation GET define que el método será de ese tipo. También puede ser POST, PUT, DELETE entre otros.
- Los parámetros del anotation definen el endpoint, siendo {id} el valor variable según el pokemon que queramos invocar.
- El método getPokemonById es el que usaremos para llamar al servicio y le pasamos por parámetro nuestro id.
- El valor de retorno es de tipo Call<>, que es una clase que devuelve Retrofit conteniendo el modelo de respuesta.

Ahora armaremos ese modelo PokemonByIdResponse:

```java
public class PokemonByIdResponse {
	@SerializedName("base_experience")
	private int baseExperience;
	private String name;
	private int id;
	
	public int getBaseExperience() {
		return baseExperience;
	}
	
	public String getName() {
		return name;
	}
	
	public int getId() {
		return id;
	}
}
```

Este modelo es la representación del json que nos devuelve la API, aunque solo toma algunos atributos, dado que no es necesario traernos todos.

Para poder llamar a la API debemos implementar Retrofit en nuestra Activity de la siguiente manera:

```java
final String URL_BASE = "https://pokeapi.co/api/v2/";

Retrofit retrofit = new Retrofit.Builder()
	.baseUrl(URL_BASE)
	.addConverterFactory(GsonConverterFactory.create())
	.build();
	
PokemonAPI pokemonAPI = retrofit.create(PokemonAPI.class);
```

Ahora debemos crear un objeto Call para llamar al endpoint de pokemon y recibir los datos que serán almacenados en nuestro modelo.

```java
Call <PokemonByIdResponse> call = pokemonAPI.getPokemonById("ditto");

call.enqueue(new Callback <PokemonByIdResponse> () {
	@Override
	public void onResponse(Call <PokemonByIdResponse> call, Response <PokemonByIdResponse> response) {}
	
	@Override
	public void onFailure(Call <PokemonByIdResponse> call, Throwable t) {}
});
```

Vamos a analizar este snippet en detalle:

- Creamos un objeto call y llamamos al método de la interfaz pasando por parámetro nuestro id de pokemon.
- Llamamos al método enqueue para llamar al servicio y por parámetro instanciamos un CallBack de Retrofit, el cual nos devolverá la respuesta de forma asincrónica.
- Si todo salió bien, en OnResponse obtendremos el objeto.
- Si salió mal, en onFailure obtenemos el error mediante t.getMessage().

Pero nos queda un paso mas, que es obtener la respuesta, dado que el objeto response del método OnResponse tiene muchos atributos, entre ellos nuestro modelo de respuesta. Para obtenerlo lo haremos de la siguiente manera:

```java
public void onResponse(Call<PokemonByIdResponse> call, Response<PokemonByIdResponse> response) {
  PokemonByIdResponse pokemon = response.body();
}
```

Pero puede que onResponse nos devuelva un status 500 o cualquiera que no sea 200, por lo que debemos controlar ese flujo:

```java
if(response.isSuccessful()){
   PokemonByIdResponse pokemon = response.body();
} else {
   Log.e("error", "Hubo un error inesperado!");
}
```

Como ven la implementación es un poco larga, pero no compleja.

Espero que este artículo les haya sido de utilidad, y nos vemos en el siguiente!