Blog

Transformando un monolito móvil: de monolitos a micro apps con React Native

Blog

En el ámbito del desarrollo móvil, enfrentarse a una aplicación monolítica puede ser un desafío considerable, especialmente cuando se requiere una evolución ágil y continua.

Este funcionamiento monolítico, por un lado, permite lanzar aplicaciones con rapidez y facilidad en el soporte, ya sea para iOS como para Android. La contracara es que aquellos beneficios se convierten, luego, en obstáculos para la evolución de dichas aplicaciones. 

Si bien estas dificultades son ampliamente conocidas y asociadas a sistemas legados (p.e. core de seguros o bancario), en los últimos años hemos encontrado un número de organizaciones presentando una problemática similar, esta vez relacionada con sus aplicaciones móviles. 

Recordamos algunos de los problemas que pueden encontrarse:

  1. Alta dependencia entre módulos: En un monolito, todos los componentes están interrelacionados, lo que implica que un cambio en una sección de la aplicación puede desencadenar problemas en otras. Esto aumenta el riesgo de errores y ralentiza la velocidad de desarrollo, ya que cualquier cambio o mejora requiere una verificación exhaustiva de toda la aplicación.

  2. Limitación en el mantenimiento y escalabilidad: Con el tiempo, el código se vuelve más difícil de gestionar debido a la falta de cohesión. La estructura monolítica impide una división clara de responsabilidades y, cada actualización o nueva funcionalidad, genera una sobrecarga en el proceso de mantenimiento. Esto hace que la aplicación no solo sea menos escalable, sino también menos flexible para adaptarse a nuevos requerimientos.

  3. Falta de autonomía en los despliegues: Al estar todos los componentes en una sola base de código, cualquier cambio requiere un despliegue completo de la app, incluso si el ajuste solo afecta a una pequeña parte. Esto disminuye la autonomía de los equipos de desarrollo y reduce la frecuencia de lanzamientos, dado que un problema en una pequeña parte de la app puede detener todo el proceso.

  4. Dificultad en la integración de nuevas tecnologías: La integración de varias tecnologías, si bien ofrece cierta flexibilidad, genera inconsistencias en la experiencia del usuario y en el flujo de trabajo de los desarrolladores. Agregar nuevas herramientas o mejoras se vuelve cada vez más complejo, lo que aumenta los tiempos de desarrollo y requiere esfuerzos adicionales de integración.

  5. Backend acoplado y bajo nivel de cohesión: El backend funciona como un monolito en sí mismo, con alto acoplamiento y baja cohesión entre sus componentes. Esto significa que cualquier cambio en la lógica de negocio o en los endpoints requerirá la coordinación entre equipos y puede desencadenar efectos en varias áreas de la aplicación. Asimismo, esto limita la capacidad de iterar y mejorar rápidamente, dado que los servicios del backend no suelen estar alineados con la lógica modular del frontend.

  6. Problemas de rendimiento y experiencia del usuario: Al depender de un monolito, la aplicación se vuelve cada vez más pesada y con mayores tiempos de carga, especialmente cuando utiliza webviews. Esto afecta directamente la experiencia del usuario, ya que los tiempos de espera y la falta de fluidez concluyen en una interfaz menos atractiva y dificultan una experiencia continua entre las secciones de la aplicación.

Este escenario, promueve la necesidad de transformar las aplicaciones hacia una arquitectura modular basada en micro apps con React Native y una separación del backend mediante Backends For Frontend (BFF). Esta estrategia nos permite, no solo mejorar la cohesión y la escalabilidad, sino también ofrecer a los usuarios una experiencia más fluida y adaptada a sus necesidades.

Esta transformación puede darse progresivamente a lo largo de fases, que de cualquier forma deberán considerar dos ramas fundamentales:

(*) Estos módulos pueden o no existir y tienen como regla que viven dentro del bundle de la aplicación
Diagrama de arquitectura de app monolítica en el frontend y el backend

Desacoplar el frontend

La separación de la lógica de la aplicación del frontend es crucial para la evolución y mantenimiento de la app. El uso de tecnologías como React Native permiten crear un único componente multiplataforma que se adapta tanto a iOS como a Android. Su utilización elimina la necesidad de desarrollar dos aplicaciones separadas, reduciendo el esfuerzo de mantenimiento y permitiendo una experiencia de usuario más coherente.

Las aplicaciones se cargan en tiempo de ejecución, lo que significa que los componentes pueden ser actualizados y desplegados independientemente, facilitando un enfoque modular. Sin embargo, esto también presenta un desafío: la comunicación con el resto de la aplicación debe ser sencilla y bien definida para evitar problemas de integración. Además, se puede configurar si se desea cargar un componente de forma dinámica o estática, lo que otorga flexibilidad a los desarrolladores.

Desacoplando el backend

Para desacoplar el backend, puede implementarse, por ejemplo, una serie de Backend For Frontend (BFF), cada uno dedicado a un flujo funcional específico y orientado a la experiencia de la pantalla que queremos mostrar. Esto permite que la lógica de negocio y las reglas, que deberían estar orientadas al dominio, se trasladen a una capa abstracta de APIs de negocio REST. Así, las micro apps pueden interactuar de forma efectiva con el backend, sin la necesidad de tener lógica o orquestación en el frontend.

Para poder llevar a cabo esta estrategia de BFF y desacoplar el proceso de inicio de sesión, puede implementarse la estrategia de compartir la sesión con el monolito mediante el uso de JSON Web Tokens (JWT), asegurando que sea stateless. Esto permite que las micro apps gestionen la autenticación de manera más eficiente, eliminando la dependencia del estado en el servidor y facilitando la escalabilidad.

La estrategia de BFF también posibilita generar pantallas que no contienen lógica ni orquestación; su único propósito es mostrar información. Esto significa que los cambios más frecuentes no afectan directamente al frontend, simplificando las actualizaciones y el mantenimiento.

(*) La cáscara mobile chequea en tiempo de ejecución el versionamiento de las MicroApps y las descargas si fuese necesario.
Diagrama de arquitectura en transición desde una app monolítica a micro apps

Ventajas y desventajas de la estrategia de micro apps

Implementar una estrategia de micro apps tiene sus ventajas y desventajas:

Ventajas:

  • Dinamismo y autonomía en despliegues: Cada micro app puede ser desplegada de forma independiente, lo que permite actualizaciones rápidas y frecuentes.
  • Reducción de duplicación de esfuerzos: Al usar React Native, se crea un único componente multiplataforma, eliminando la necesidad de desarrollar dos aplicaciones separadas.
  • Facilidad de mantenimiento: La separación de responsabilidades facilita la identificación de problemas y la implementación de mejoras.

Desventajas:

  • Punto de indirección y posible fallo: La carga dinámica de contenido puede introducir un punto de fallo, lo que podría afectar la experiencia del usuario.
  • Tiempos de espera: Los usuarios pueden experimentar tiempos de espera mientras se carga el contenido dinámico.
  • Desafíos de comunicación: Inicialmente, la integración entre micro apps y el resto de la aplicación puede requerir inversiones de tiempo significativas.
  • Aumento del tamaño del bundle: La estrategia de micro apps puede resultar en un bundle más grande, lo que incrementa el peso de la aplicación en los dispositivos de los usuarios.

Para mitigar algunas de estas desventajas, puede implementarse una solución que permita configurar si el bundle es dinámico o estático. Esto asegura que, si el contenido es estático o local, la carga sea instantánea.

Diagrama de arquitectura en el modelo TO BE de una app con microfrontends

Conclusiones

La transformación de una aplicación monolítica móvil, con un backend altamente acoplado y múltiples enfoques tecnológicos, presenta desafíos significativos. En este caso, la necesidad de desacoplar tanto el frontend como el backend, simplificar la estructura y mejorar la experiencia del usuario, puede llevarnos a adoptar una estrategia de micro apps con React Native y a crear una capa de BFFs especializada en cada flujo funcional. Además, puede trasladarse la lógica de negocio a APIs REST para obtener un backend más cohesionado.

Esta estrategia permite obtener autonomía en los despliegues, mejorar la modularidad, y resolver uno de los grandes problemas de las aplicaciones móviles: la duplicación de esfuerzos al desarrollar para diferentes plataformas. Sin embargo, la introducción de micro apps y cargas dinámicas también trae consigo nuevos retos, como los tiempos de carga para los usuarios y el punto de falla potencial al manejar contenido dinámico. Para mitigarlos, puede adoptarse un enfoque híbrido que permita decidir si una micro app es cargada de manera dinámica o estática, dependiendo de las necesidades.

Es importante resaltar que no hay reglas fijas para este tipo de arquitecturas. Las decisiones tomadas deben estar alineadas con la naturaleza de la aplicación, su experiencia de usuario y su complejidad. La estrategia adoptada en un proyecto puede ser muy exitosa, mientras que, en otro con diferente alcance y requisitos, puede no ser la más adecuada. Cada solución debe evaluarse en función de las necesidades específicas del producto, los usuarios y las limitaciones técnicas.

Al final, lo que buscamos es encontrar un equilibrio entre la flexibilidad, la escalabilidad y la simplicidad de la arquitectura para que la aplicación siga siendo robusta y mantenible a largo plazo.

Contacto

Contactanos

¿Cómo podemos ayudarte?