Manejando Llamadas de Red como un Pro en Flutter

Carlos Millan
8 agosto, 2019

. . .

Traducción al español del artículo escrito por Sahil Kumar, el cual puedes encontrar el original en inglés aquí.

Si ya estás enamorado de Flutter, debes haber creado muchas aplicaciones a partir de ahora. Algunas de ellas son quizás pequeñas pantallas de una sola pantalla y otras pueden ser una aplicación completa. También creé muchos, al principio todo parece fácil ya que eran aplicaciones pequeñas, pero una vez que comencé a crear algunas aplicaciones más grandes que se basan en hacer muchas llamadas de red, comencé a enfrentar varios errores y mi aplicación comienza a comportarse mal. Todo esto sucedía porque no estaba manejando mis llamadas API correctamente.

En este blog, aprenderemos cómo superar todos estos problemas mediante la creación de una aplicación de películas de muestra que muestre una lista de películas populares que utilizan la API TMDB.

Algunos Prerequisitos

Como vamos a implementar esta aplicación usando el patrón BLOC, debe conocer los conceptos básicos de Streams y StreamControllers. Algunos conocimientos básicos de los códigos de respuesta HTTP y el patrón del repositorio también lo ayudarán a comprender esto más fácilmente.

La arquitectura básica de nuestra aplicación será así.

Pasos que vamos a seguir en este artículo:

  1. Crear una clase auxiliar de API.
  2. Excepciones de apps personalizadas.
  3. Clases de modelo MovieResponse.
  4. Una clase de respuesta API genérica.
  5. Una clase de repsitorio para obtener datos de las APIs.
  6. Una clase bloc para consumir eventos de UI y enviar streams.
  7. Una UI para mostrar todos los datos.

Una respiración profunda aquí, justo antes de sumergirnos en la dicha absoluta.

Breathe Guru Studio GIF by True and the Rainbow Kingdom - Find & Share on GIPHY

Crear una clase auxiliar de API

Para establecer comunicación entre nuestro servidor remoto y la aplicación, utilizamos varias APIs que necesitan algún tipo de métodos HTTP para ejecutarse. Entonces, primero vamos a crear una clase auxiliar de API base, que nos ayudará a comunicarnos con nuestro servidor.

La clase auxiliar se explica por sí misma. Solo contiene un método HTTP Get que luego puede ser utilizado por nuestra clase de repositorio. También puede agregar otros métodos HTTP como («POST«, «DELETE«, «PUT«) en esta clase.
Debes preguntarte cuáles son todas esas excepciones. Nunca escuché nada sobre ellos. No se preocupe, todas esas son solo nuestras excepciones de aplicaciones personalizadas que crearemos en nuestro próximo paso.

Crear excepciones de aplicaciones personalizadas

Una solicitud HTTP en ejecución puede devolver varios tipos de códigos de estado en función de su estado. No queremos que nuestra aplicación se comporte mal si la solicitud falla, por lo que vamos a manejar la mayoría de ellas en nuestra aplicación. Para hacerlo, crearemos nuestras excepciones de aplicaciones personalizadas que podemos lanzar según el código de estado de respuesta.

Crear clases de modelo MovieResponse

Como estamos trabajando con TMDB para obtener nuestras películas populares. tenemos que crear una clase básica de modelo de dart que contendrá los datos de nuestra película.

Crear una clase genérica ApiResponse

Para exponer todos esos errores HTTP y excepciones a nuestra interfaz de usuario, vamos a crear una clase genérica que encapsule tanto el estado de la red como los datos que provienen de la API.

Crear una clase de repositorio para recuperar datos de las API

Como dije al principio que estamos creando esta aplicación con la idea de implementar una buena arquitectura. Vamos a utilizar una clase de repositorio que actuará como intermediario y una capa de abstracción entre las APIs y el BLOC. La tarea del repositorio es entregar datos de películas al BLOC después de obtenerlos de la API.

Crear el Bloc Movie

Para consumir los diversos eventos de IU y actuar en consecuencia, crearemos un Bloc llamado Movie. Su tarea es solo manejar el evento «buscar lista de películas» y agregar los datos devueltos al Sink que luego pueden ser escuchados fácilmente por nuestra interfaz de usuario con la ayuda de StreamBuilder.

La parte principal del blog viene aquí, ya que vamos a manejar todas esas excepciones que creamos. Lo básico que estamos haciendo aquí es pasar diferentes estados de nuestros datos a nuestra interfaz de usuario utilizando StreamController.

Estado: Loading -> Notifica a la interfaz de usuario que nuestros datos se están cargando actualmente.

Estado: Completado -> Notifica a la interfaz de usuario que nuestros datos ahora se han recuperado correctamente y podemos mostrarlos.

Estado: Error -> Notifica a la interfaz de usuario que obtuvimos un error o una excepción al recuperar nuestros datos.

Crear una pantalla Movie para mostrar películas populares

Para reaccionar a los estados de nuestros datos, crearemos un widget con estado llamado MovieScreen y escucharemos todos los cambios de estado utilizando StreamBuilder.

Cosas que hicimos en nuestra MovieScreen ->

  • Creamos un nuevo objeto de nuestra clase MovieBloc en el método initState () que también comenzará a buscar nuestras películas populares.
  • Disposed nuestro objeto MovieBloc en el método dispose() que lanzará todas nuestros streams.
  • Creé un widget StreamBuilder en el body de nuestro Scaffold que tomará _bloc.movieListStream como un stream y comenzará a escuchar cualquier cambio en él.
  • Manejé los tres estados de nuestros datos usando un switch case y devolviendo un widget según el estado de los datos.

Lo hicimos, nuestra aplicación ahora funciona perfectamente y también manejamos nuestra llamada de red como un profesional. Nuestros usuarios nunca sufrirán ahora.

Yeah GIF - Find & Share on GIPHY

Puede encontrar el codígo completo funcional aquí 👇

https://github.com/xsahil03x/flutter_network_handling

Bonus

Esta práctica no se limita al patrón BLOC, sino que también se puede usar fácilmente con otras técnicas de administración de estado, como el Scoped Model y Provider, por ejemplo:

Entonces este modelo se puede observar fácilmente utilizando el widget ScopedModelDescendant en su interfaz de usuario.

22

2 comentarios

  • Joel Rodrigo

    Gracias por la traduccion

  • Alejandro

    Excelente tutorial, hay un solo problema, como haces para manejar respuestas paginadas?, intente hacerlo y al hacer el llamado, no agrega las nuevas peliculas de la respuesta, sino que «limpia» los registros anteriores (pagina 1) y agrega la nueva respuesta (pagina 2), voy a ver si puedo solucionarlo y lo subiré acá, como comentario.

Deja un comentario

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

Comunidades en Español