retrofit

Ya te habrás dado cuenta de que muchos de los proyectos Android que has desarrollado necesitan información de alguna API para después trabajar con ellos. Para facilitarte este trabajo te recomiendo utilizar dos librerías: Retrofit y Gson.

Retrofit te va a ayudar a hacer peticiones y procesar las respuestas de las APIs y con Gson simplificarás la transformación entre los datos de un JSON y los de tu lógica de negocio. Verás que bien funcionan juntas y lo fácil que es obtener datos con ellas para tu app.

Para ilustrar el post me he servido de la API de videojuegos Internet Game Data Base (IGDB).

Paso 1: Incluir Retrofit y Gson en tu proyecto

Para que puedas utilizar Retrofit y Gson tienes que incluir estas dos líneas en tu fichero build.gradle:

Pero tienes otra opción para incluir las dos librerías a la vez usando retrofit2:converter-gson que ya se encarga de añadir todas las dependencias de Retrofit y Gson necesarias:

Ya tienes las dos librerías incluidas en tu proyecto, primer paso concluido ¡al siguiente!

Paso 2: Hacer un builder personalizado de Retrofit

Para poder utilizar Retrofit necesitas crear un builder que te servirá para comunicarte con la API elegida.

Si te fijas en la segunda línea verás que hay que escribir la url base de la API a la que harás las peticiones. La obtienes de la documentación proporcionada por el creador de la API.

En la siguiente línea hay que indicar la forma de convertir los objetos de la API a los de tu negocio y viceversa, aquí es donde especificas que vas a utilizar Gson.

Este builder lo necesitarás para hacer las llamadas a la API, así que procura que sea accesible.

Paso 3: Usar Gson para pasar de Json a Java

Si no has trabajado con Gson verás que no tiene mucho misterio.

Primero necesitas conocer la estructura del Json que va a devolverte la API ya que no hay un patrón establecido. Aquí tienes la estructura de un videojuego proporcionada por IGDB:

Después tienes que crear la estructura de clases para almacenar la información que te resulte útil.

Los valores que hay entre ‘{‘ y ‘}’ son los atributos de la clase en cuestión. Por ejemplo:

Se traduciría a:

@SerializedName lo utilizarás para especificar que valor irá en cada atributo de la clase, aunque si lo llamas igual puedes omitirlo. Por ejemplo:

Sólo pondrías @SerializedName en el “id” ya que el nombre del atributo de la clase no coincide con el de la estructura del Json. Los otros, al coincidir, te los puedes ahorrar.

Los valores entre ‘[‘ y ‘]’ forman una lista. Por ejemplo:

Sería una lista de la siguiente clase:

Resumiendo, la clase GameResponse podría ser la siguiente:

Y de esta forma tendrías tu modelo para obtener los datos de la API.

Paso 4: Crear los servicios

Para hacer una petición a la API tienes que crear una interfaz con todos los servicios que quieras utilizar. Aquí tienes unos ejemplos:

En el código de arriba hay dos servicios uno para obtener todos los videojuegos con una determinada palabra clave (“search”) y otro que obtendrá el videojuego que coincida con el id pasado por parámetro.

Usando Call realizas la llamada a la API, además ahí es dónde indicarás el tipo de dato que esperas obtener, en estos ejemplos la respuesta será una lista de 0 a N videojuegos.

Te habrás fijado que hay palabras seguidas del símbolo ‘@’ que dan funcionalidad a los servicios, haciéndolos dinámicos y reutilizables, voy a explicarte las más típicas:

@GET y @POST

Cada una de las peticiones que hagas utilizarán o el método GET o el POST (eso lo indicará el creador de la API). El parámetro será la url de la petición.

Recordarás que en el builder de Retrofit que hiciste en el paso 2 incluiste una url base de la api, de esta manera la url completa será la unión de la url base y el valor que hayas incluido como parámetro, por ejemplo: “https://igdbcom-internet-game-database-v1.p.mashape.com/games/”.

@Header y @Headers

Los usarás para especificar los valores que vayan en la sección “header” de la petición.

Header remplaza el valor que tuviera anteriormente la cabecera que especifiques por el nuevo:

Headers admite una lista de cabeceras sin sobreescribirlas, incluso aunque tengan el mismo nombre:

@Path

Quizá en la url de tu petición tengas que incluir un identificador o cualquier otro valor para obtener información sobre algo específico, y como no vas a hacer una petición para cada caso en concreto puedes usar @Path como un atributo en tu método de llamada:

De esta forma usando @Path estas indicando que el parámetro idGame sustituirá a {id} en la url.

@Query

Usa @Query si la petición que vas a hacer necesita parámetros (los valores que van después del ‘?’ en una url), de esta forma podrás reutilizar la misma petición para obtener resultados distintos.

En este caso utilizarías el parámetro “search” para especificar una palabra clave que deberá aparecer en todos los juegos que quieres obtener (por ejemplo “zelda”):

Con esto ya has visto lo básico para crear servicios, ahora toca hacer peticiones.

Paso 5: Pedir datos a la API

Esto lo harás utilizando una instancia del builder que creaste en el paso 2 y especificando la clase proveedora de servicios que hiciste en el paso 4.

Repasa conmigo estas líneas.

línea 1

void getGames(Callback> callback, String search) {

Callback es una interfaz proporcionada por Retrofit. En ella puedes especificar tu objeto de respuesta, en este caso será una lista de videojuegos.

Callback tiene dos métodos: void onResponse(Call call, Response response) y void onFailure(Call call, Throwable t), que te explicaré más adelante.

El parámetro “search” lo necesitarás para invocar el servicio, en seguida lo verás.

línea 2

ServicesProvider servicesProvider = retrofit.create(ServicesProvider.class);

Con esta instrucción especificas que proveedor de servicios vas a utilizar, en este caso el que creaste en el paso 4.

línea 3

servicesProvider.getGames(search).enqueue(callback);

Ya por último llamas al servicio que quieres invocar para hacer la petición, pasándole los parámetros que sean necesarios, en este caso “search”.

Con enqueue la llamada sera asíncrona, de esta forma cuando termine la petición según si ha tenido éxito o no llamará a los métodos onResponse u onFailure del callback respectivamente.

¿Cómo quedaría la clase completa con los dos servicios que creaste en el paso 4?

Fácil ¿verdad? Pues a por el último paso.

Paso 6: Capturar la respuesta

Ya sólo te queda obtener la respuesta. Esto lo harás en la clase en la que hayas implementado la interfaz Callback de Retrofit que viste en el paso 5. Por supuesto, puedes usar otros métodos para devolver la respuesta de la API, como crear tu propio Callback o usar librerías como EventBus.

Si todo ha ido bien, lo único que tienes que hacer es obtener el body del parámetro “response” del método onResponse, que coincide con el tipo de objeto que le pasaste.

Resumen

Esto es lo que has hecho:

  • Paso 1: Incluiste las librerías Retrofit y Gson a tu proyecto
  • Paso 2: Creaste un builder de Retrofit
  • Paso 3: Con Gson montaste la estructura de la respuesta usando clases Java
  • Paso 4: Especificaste los servicios encargados de llamar a la API
  • Paso 5: Pediste los datos a la API
  • Paso 6: Capturaste la respuesta

Siguiendo estos pasos y con una UI sencilla tendrías un bonito proyecto. Puedes consultar el mío aquí.

Como puedes ver ha sido muy fácil. Lo siguiente es que hagas tu propio proyecto y practiques con estas librerías.

Si tienes ganas de un poco más, a continuación explicaré lo que son los interceptors y como te pueden ayudar a mejorar el trabajo con Retrofit.

Paso Extra: Crear Interceptors en Retrofit

Los interceptors son elementos que capturan las llamadas a la API para agregarle funcionalidad extra, como indica su nombre, interceptará la request para que puedas incluir valores que te interesen. Te muestro dos casos útiles.

Utilidad 1: Eliminar los valores recurrentes en los servicios

Dos de valores más repetitivos en las llamadas a la API son los headers y los params.

En la API de IGDB hay que incluir dos valores en la cabecera de cada llamada: la clave y el accept ¿y si en lugar de escribirlos en cada servicio usando @Headers utilizas un interceptor?

También puedes hacer lo mismo con los params, la API de IGDB te ofrece la posibilidad de filtrar los campos que quieres que te devuelva la petición usando el parámetro “filter”, si no te interesan todos los campos de un videojuego ¿para qué pedir de más? Te muestro como quedaría en el interceptor que hiciste antes:

Utilidad 2: Desplegar un log para comprobar los datos

Usando un interceptor puedes obtener un log de la request, de esa forma sabrás que llamada has hecho y que ha devuelto de un vistazo.

Para utilizar esta funcionalidad debes agregar la siguiente librería al fichero gradle:

Lo siguiente es crear el interceptor para el logging:

Los niveles de detalle, de menos a más detallados son: NONE, BASIC, HEADERS y BODY.

El resultado del log será similar al siguiente:

Se puede ver la llamada y la respuesta, muy útil.

Incluir los interceptor a Retrofit

Ya tienes un par de interceptors creados, ahora tienes que incorporarlos a tu builder de retrofit.

Basta con crear un cliente que incluya todos los interceptors que quieras:

Y que luego incluirlo en el builder de retrofit que hiciste en el paso 2:

Conclusión

Retrofit y Gson serán tus grandes aliados en todos los proyectos en los que necesites acceder a un servicio http de alguna API, y como has visto es muy sencillo de usar y de darle unas funcionalidades muy útiles.

Ahora es tu turno, sigue estos pasos y escribe un comentario explicando que te parece utilizar estas librerías en tus proyectos.

¡Un saludo!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *