Arquitectura de microaplicaciones: Un ahorro de tiempo garantizado

Compartir por correo electrónico

Para garantizar una mejor mantenibilidad y escalabilidad de nuestras aplicaciones, a menudo tenemos que descomponer nuestra aplicación en una multitud de microservicios con su propia lógica. Estos microservicios deben ser lo más autónomos posible y cumplir una función específica para poder reutilizarlos en diferentes contextos.
Esta arquitectura está enormemente implantada en el desarrollo del lado del Backend y, por tanto, más madura. Observamos, por ejemplo, la aparición de ciertas bibliotecas de registro, API-gateway que permiten soportar una arquitectura de este tipo. Sin embargo, es más difícil arquitecturar su aplicación FrontEnd (Angular, Reaccionaro VueJS) en microservicios y menos aún para implementarlo en el mundo móvil que por definición es un monolito.
El objetivo de este artículo es demostrar que es posible modularizar una aplicación móvil, en nuestro caso bajo Fluttery, sobre todo, cómo construirlo a partir de varias microaplicaciones.

Visión global

El desarrollo de una aplicación modular equivale a establecer un paralelismo con un conjunto de bloques diferentes, cada uno de los cuales cumple funciones muy específicas y tiene el menor número posible de dependencias externas. En nuestro caso, esta modularidad está presente para disponer de varias variantes de una misma aplicación y, por tanto, poder presentar en un tiempo mínimo una misma aplicación con diferentes funcionalidades.
Así pues, esta arquitectura de microaplicaciones permitirá, en primer lugar, presentar una multitud de variantes de una aplicación y, en segundo lugar, un desarrollo más robusto. En efecto, esta arquitectura permitirá un mantenimiento y una escalabilidad de la aplicación más optimizados. El mantenimiento de la aplicación sólo se realizará sobre la microaplicación defectuosa o en evolución y la escalabilidad de la aplicación consistirá en añadir una microaplicación en la aplicación. En consecuencia, el despliegue o la actualización de la funcionalidad se hará sólo sobre una parte de la aplicación limitando al máximo una regresión de la aplicación (defecto introducido en el software con motivo de correcciones de errores o de cualquier cambio establecido).
Más concretamente, las microaplicaciones permiten el desarrollo utilizando diferentes "repositorios" para cada microaplicación. En la mayoría de los casos, este último está orientado a las funcionalidades del negocio. También permite que equipos separados trabajen en cada microaplicación.

Antes de emprender la implantación de este tipo de arquitectura en FlutterEn este caso, vamos a dar un paso atrás y analizar las capacidades de las plataformas cruzadas frente al desarrollo nativo. En esta parte se evaluará el rendimiento de los diferentes frameworks multiplataforma según varios criterios (Productividad, mantenibilidad...). Veremos, posteriormente, una comparación basada en los mismos criterios y poniendo en contraposición las arquitecturas de micro-aplicaciones y las monolíticas.

Plataformas cruzadas VS Nativo

Los frameworks multiplataforma permiten a los desarrolladores crear aplicaciones móviles compatibles con múltiples sistemas operativos, en este caso, iOS y Android. Dan la posibilidad de escribir el código una vez y luego ejecutarlo en cualquier lugar en otras plataformas, lo que les permite lanzar el producto/software de forma más rápida, segura y con mejor calidad. Pero veamos si el rendimiento está ahí.
El desarrollo de aplicaciones nativas evita la complejidad de crear un producto sostenible que abarque el desarrollo de aplicaciones en varias plataformas y se centra en crear una aplicación competente que se mantenga cerca de la plataforma de destino: Android, iOS, etc.
Los frameworks multiplataforma, en cambio, buscan generar una aplicación que llegue al mayor número de personas posible abarcando muchos dispositivos durante el proceso de programación y creación.

CriteriosNativoPlataformas cruzadas
CosteAlto coste de desarrolloCoste de desarrollo relativamente bajo
Reutilización del códigoFunciona para una plataformaUn solo código puede utilizarse en varias plataformas, para facilitar la portabilidad
Acceso a los dispositivos (cámara, etc.)El SDK (kit de desarrollo de software) garantiza el acceso a la API del dispositivo sin ningún obstáculoNo se garantiza el acceso a todas las API de los dispositivos
Coherencia en la interfaz de usuarioConforme a los componentes de la interfaz de usuario del dispositivoCoherencia limitada con los componentes de la interfaz de usuario del dispositivo
RendimientoRendimiento fluido, ya que la aplicación está desarrollada para el sistema operativo de los dispositivosAlto rendimiento, pero los retrasos y los problemas de compatibilidad de hardware no son infrecuentes

La cuestión de elegir un desarrollo nativo o multiplataforma se basa en gran medida en las necesidades que tengas y en el proyecto en cuestión.
Por último, las ventajas de una aplicación nativa son:

  • Alto rendimiento
  • Funcionalidad robusta
  • Experiencia de usuario fluida

Y el de una aplicación multiplataforma:

  • 70 a 90% código reutilizable
  • Fácil mantenimiento y actualizaciones
  • Un mayor alcance
  • Menor tiempo de comercialización

Sin embargo, a lo largo de los años han surgido multitud de marcos, y podemos distinguir dos tipos:
Aplicaciones nativas multiplataforma: Cada sistema operativo tiene su SDK (Software Development Kit) y su pila tecnológica: Java o Kotlin para Android y Objective-C o Swift para las aplicaciones de iOS. Los desarrolladores de aplicaciones multiplataforma construyen una API unificada que se ejecuta en un SDK nativo, utilizan IDEs nativos y construyen aplicaciones para iOS y Android que comparten el mismo código base. Las aplicaciones nativas multiplataforma se construyen principalmente con Xamarin, React Nativey Flutter.
Aplicaciones híbridas: Como los SDK de iOS y Android incluyen componentes web avanzados, es posible crear partes de la interfaz gráfica de usuario (GUI) de una aplicación con HTML5, CSS y JavaScript. A continuación, los desarrolladores envuelven el código en una "WebView", un navegador integrado en una aplicación móvil, que hace que el contenido sea como un buen sitio web antiguo. Algunas aplicaciones híbridas incluso interactúan con el hardware del smartphone, aunque su funcionalidad puede ser limitada. Los marcos de desarrollo de aplicaciones híbridas más prometedores actualmente en el mercado son Apache Cordova y Iónico.
Aplicaciones nativas multiplataforma como Flutter llegó después de las aplicaciones híbridas con el fin de superar la falta de rendimiento con el uso de Webview y el uso de widgets nativos desde un punto de UI / UX.

Productividad

La productividad durante el desarrollo de una aplicación puede medirse en función de varios puntos:
La curva de aprendizaje: la capacidad de un nuevo desarrollador en el Framework ha desarrollado una funcionalidad más compleja y rápida.
Reutilización del código: ¿El código producido por el desarrollador es exportable o puede utilizarse en diferentes plataformas?

La curva de aprendizaje parece ser cada vez más alta a medida que te acercas al desarrollo nativo. De hecho, es bastante fácil de usar React Nativeespecialmente si ya ha utilizado Reaccionar o JavascriptEl desarrollo de la web se acerca mucho al concepto de componente. Si nos movemos hacia un Framework más cercano al hardware como FlutterEn cuanto a la programación reactiva, observamos que el aprendizaje es bastante rápido pero es necesario aprender Dart, y la programación reactiva no es del todo intuitiva. Por último, el desarrollo nativo como IOS con Objectif-C o Android con Kotlin siguen siendo lenguajes complejos y densos de aprender. Sin embargo, hay muchas más posibilidades tanto técnicas como funcionales.
En cuanto a la capacidad de reutilizar el código, los frameworks multiplataforma llevan claramente la delantera con la posibilidad de producir múltiples aplicaciones con un único código. De hecho, el desarrollo nativo obliga al desarrollador a escribir la misma funcionalidad en varias plataformas.

Utilización de recursos materiales

El desarrollo de aplicaciones nativas ofrece acceso a todas las funciones de hardware del dispositivo de destino (cámara, geolocalización, etc.). Sin embargo, las aplicaciones multiplataforma tienen acceso a la mayoría de estas funcionalidades a través de un puente o a través del navegador (para Webview). Estoy pensando en la geolocalización, la cámara o incluso el micrófono. El acceso a los recursos de hardware no es realmente un punto débil de las aplicaciones multiplataforma. Las comunidades, cada vez más numerosas, incluso facilitan el acceso a ellos de forma nativa o mediante la adición de plugins. Para un uso clásico de las funciones de hardware, las dos soluciones están al mismo nivel.

Código abierto, propietario, con licencia (coste)

La ventaja de los frameworks multiplataforma más famosos como Flutter o React Native es que son de código abierto y gratuitos. No necesitan tener un entorno concreto para ser utilizadas, a diferencia del desarrollo para IOS, por ejemplo. De hecho, la elección de optar por aplicaciones multiplataforma se debe en parte al coste del desarrollo de IOS. Este último es bastante restrictivo y nos obliga a tener un entorno específico que aumenta el coste del desarrollo.

Mantenimiento

El mantenimiento de los programas informáticos puede evaluarse según dos criterios más precisos:

  • Mantenimiento evolutivo: La capacidad de cambiar o corregir errores con mayor o menor facilidad / rapidez.
  • Obsolescencia: ¿Tiene futuro la tecnología utilizada? ¿Está respaldada por una comunidad importante?

Si adoptamos una visión puramente lógica, el mantenimiento evolutivo de una aplicación que estuviera en dos plataformas (Android / IOS) llevaría el doble de tiempo en desarrollo nativo que en desarrollos multiplataforma.
Desde el punto de vista de la obsolescencia, ya sea en plataformas cruzadas con nativos Flutter y Reaccionar o en Android e Ios nativos, las posibilidades de que estos marcos desaparezcan siguen siendo escasas. De hecho, Flutter cuenta con el apoyo de Google y su comunidad crece día a día, React Native es mantenido por Facebook y cuenta con una gran comunidad heredada en particular de React. Además, Android e IOS son los sistemas operativos más populares en todo el mundo.
Por otro lado, los frameworks como Ionic basados principalmente en Webview están cada vez más obsoletos desde el punto de vista del rendimiento.
Por último, la elección del entorno de desarrollo para su aplicación dependerá de las necesidades y requisitos de ésta y de las capacidades de los desarrolladores. Si los equipos proceden del mundo WEB, la transición a React Native no será confuso. Flutter sigue siendo hoy en día la solución multiplataforma más cercana al hardware, pero requiere el aprendizaje de un lenguaje bastante nuevo y con poca retroalimentación, Dart. Por último, para producir una aplicación de calidad que funcione bien en el desarrollo nativo, la curva de aprendizaje sigue siendo alta.

La figura anterior resume las ventajas y desventajas de las distintas tecnologías que pudimos abordar en función de criterios de rendimiento, acceso a los equipos y costes.

Arquitectura monolítica VS microaplicación

La elección de la arquitectura depende, de nuevo, de las necesidades y requisitos del proyecto, pero también del personal que trabajará en la aplicación. No obstante, vamos a basarnos en criterios (similares a los de la parte anterior) que nos permitan valorar las ventajas e inconvenientes de cada una.

Productividad

Los usos y prácticas de los últimos años han evolucionado hacia arquitecturas de microaplicaciones. Sin embargo, el pasado monolítico sigue presente en nuestras formas de desarrollar aplicaciones y la curva de aprendizaje para que los desarrolladores entiendan y utilicen una arquitectura de este tipo no es fácil. A continuación veremos las distintas ventajas de una arquitectura de microaplicaciones, pero es interesante destacar una ventaja estrechamente vinculada a la productividad (desarrollo): La posibilidad de centrarse en la funcionalidad a desarrollar y no en la forma de integración en la futura aplicación. Desde este punto de vista, dicha arquitectura permite al desarrollador ganar mucho en productividad.
Cuando se desarrolla en una arquitectura monolítica, en la mayoría de los casos es necesario conocer el entorno en el que se integra la funcionalidad y tener conocimiento de la lógica de negocio de la aplicación. En el caso de una arquitectura de microaplicaciones, el alcance es restringido y, por lo tanto, la formación de un nuevo desarrollador para integrar el desarrollo de una aplicación es más corta con una arquitectura de microaplicaciones.
Además, esta capacidad de crear un ladrillo autónomo e independiente, y no una característica más de una aplicación, facilita y optimiza la reutilización en multitud de aplicaciones. Por supuesto, las arquitecturas monolíticas permiten reutilizar módulos, componentes o incluso servicios, manteniéndose dentro de los límites de la aplicación.
Por último, lo que más afecta a la productividad con la arquitectura de microaplicaciones es la instalación y el "cableado" de los diferentes ladrillos. En efecto, será necesario dedicar un equipo / un desarrollador a la implementación del punto central de la aplicación (el orquestador). Pero, ¿no se ahorra el tiempo perdido en esta implementación durante la puesta en marcha de nuevas funcionalidades?

Utilización de recursos materiales

En este punto, la adopción de una u otra arquitectura no repercute en los recursos materiales disponibles.

Mantenimiento

También en este caso, una arquitectura de microaplicación presenta ventajas no despreciables durante el mantenimiento de una aplicación. Podemos observar, por ejemplo, la capacidad de localizar un error/bug más fácilmente que en un monolito. En efecto, al ser más clara la separación de la aplicación con una microarquitectura, el problema es rápidamente identificable. Además, la implementación de una batería de pruebas específicas para la microaplicación simplifica el uso de las pruebas y reduce el riesgo de regresión durante una actualización.
Uniendo la idea anterior, la evolución de una aplicación siguiendo una arquitectura de microaplicaciones se simplifica enormemente. En efecto, la implementación de una nueva funcionalidad equivale a crear un nuevo ladrillo autónomo e independiente (microaplicación) con entradas y salidas bien definidas. El proceso de evolución en una arquitectura monolítica requiere una contextualización para poder implementar nuevas funcionalidades y sobre todo dónde.

Contexto y casos de uso

El valor añadido de una arquitectura de microaplicaciones es tener la capacidad de modular una aplicación en una multitud de microaplicaciones. Esta modularización tiene varias ventajas.

Figura 1 - Diagrama que destaca el valor añadido de las arquitecturas "micro"

Actualmente, los microservicios son cada vez más populares porque permiten distribuir los costes a nivel de desarrollo pero también a nivel técnico. En el caso de las microaplicaciones destinadas a móviles o tabletas, el verdadero valor añadido reside en el plan de desarrollo con la posibilidad de asociar una lógica de negocio con un equipo de desarrollo (desde el microservicio en el lado del backend hasta la aplicación en el lado del microfrontón). Técnicamente, las aplicaciones para móviles o tabletas serán en todos los casos un monolito al final del ciclo.

Al implementar una arquitectura de micro-aplicaciones, la capacidad de producir una aplicación con diferentes variaciones se simplifica. En efecto, esta segmentación permite modular nuestra aplicación y hacerla personalizable.

Este tipo de arquitectura no es adecuada para todos los casos de uso y especialmente para todas las aplicaciones. Para que haya un verdadero valor añadido con esta arquitectura, la aplicación debe ser grande e implicar a un número importante de desarrolladores.

Arquitectura elegida

La infraestructura de una aplicación, las bases de datos, las llamadas a la API, así como los frameworks, están en constante evolución. Pero este no es necesariamente el caso de las necesidades del negocio. Partiendo de este principio, tiene más sentido orientar nuestra forma de segmentar nuestra aplicación en el negocio.
La arquitectura hexagonal creada por Alistair Cockburn garantiza la reutilización de la lógica empresarial al hacerla agnóstica a la técnica. Así, la modificación de la pila no tendrá ningún impacto en el código del dominio. Un concepto clave de esta arquitectura es poner toda la lógica de negocio en un lugar llamado el dominio.

Figura 2 - Principio de una arquitectura hexagonal

La arquitectura hexagonal puede ser la solución, ya que tiende a aislar una aplicación en tres capas distintas:

Esta capa contiene las entidades existentes en el dominio. En esta capa, no nos importa cómo exponer los datos al usuario o cómo se almacenarán. Las entradas/salidas se realizan únicamente mediante interfaces. Para ello, hay que tener en cuenta que el negocio no debe depender de nada y, por tanto, nunca debe estar vinculado ni a la capa de Aplicación ni a la de Infraestructura.

Es en esta capa donde la Infraestructura se comunicará con el Dominio a través de las interfaces. Aquí se considera que la capa de Aplicación conoce el Dominio pero nunca debe estar vinculada a la Infraestructura. Es aquí donde, por razones de negocio, podemos enriquecer, comparar y filtrar los elementos devueltos por las interfaces del Dominio sin preocuparnos de la implementación en el lado de la Infraestructura. Es común hablar en esta capa de Handler.

La arquitectura hexagonal considera que el Dominio está en el centro de la aplicación. De hecho, la capa de infraestructura podrá comunicar e invocar los objetos del Dominio a través de las interfaces. ¡Cuidado, la infraestructura conoce la capa de la Aplicación pero no al revés! De esta manera, si quieres cambiar las APIs de terceros, hacer doble escritura o cambiar el modelo de datos, todo lo que tienes que hacer es recrear un adaptador dedicado en la capa de Infraestructura respetando la interfaz del Dominio.

Esta arquitectura se centra principalmente en un ámbito empresarial concreto. Sin embargo, en nuestro caso, queremos aglutinar multitud de dominios de negocio (micro-aplicaciones) y poder, a partir de estas micro-aplicaciones, crear una única aplicación. Esta capacidad de hacer residir varias micro-aplicaciones en una sola se basa en un orquestador. Un punto de entrada para integrar todas nuestras micro-aplicaciones. Además, este es un elemento importante que surge con bastante frecuencia en la segmentación de nuestras aplicaciones. Ya sea para microservicios con el sistema API-gateway o para contenedores (docker) con docker-compose o Kubernetes, siempre hay un orquestador, un punto de entrada para gestionar todos los ladrillos.

Aplicación

Por lo tanto, el POC realizado se basó en el concepto de arquitectura hexagonal. Aunque la arquitectura hexagonal permite un aislamiento óptimo del negocio, no nos permite segmentar nuestra aplicación a gran escala. En efecto, esta arquitectura interviene sobre un componente de negocio específico y no sobre el conjunto de las diferentes lógicas de negocio.
Cuando se habla de segmentación, siempre es importante pensar en cómo orquestar todas estas partes segmentadas. En nuestro caso, la aplicación está segmentada en multitud de paquetes, y el orquestador está representado por el shell (en azul en la figura inferior). Sin embargo, podemos observar varios tipos de paquetes:

  • Microaplicación empresarial: Es una interfaz gráfica completa. Cumple una función empresarial específica y su punto de entrada es un widget de alto nivel. Estos paquetes respetan una arquitectura hexagonal. Son estos paquetes los que se pueden considerar como micro-apps porque manejan datos de negocio (en naranja en la figura de abajo). Forman parte de la lógica del negocio.
  • Micro-aplicación funcional: Es un widget como un botón, una entrada... reutilizable en toda la aplicación así como en todos los paquetes. Son interfaces de usuario transversales a la aplicación y en general a cualquier aplicación. Estos paquetes no incluyen datos de negocio sino sólo datos de presentación. Forman parte de la lógica de negocio.
  • Microaplicación técnica: Es una micro-aplicación que está presente para la lógica técnica. Encontramos en particular la gestión de la persistencia de los datos y la gestión de los tipos. Cabe señalar que estos paquetes no tienen una interfaz de usuario. Forman parte de la lógica de la infraestructura.
Figura 3 - Diagrama de la arquitectura de la microaplicación en Flutter

La cáscara

Representa el punto de entrada de nuestra aplicación y nos permite configurar la aplicación según varias entradas. En efecto, el shell recupera varias informaciones del entorno para construir la aplicación específica. Hay tres archivos en particular:

  • El fichero de configuración contiene todas las variantes disponibles de la aplicación. Este fichero es el resultado de un estudio superior para determinar las diferentes compatibilidades entre los paquetes y las variantes que pueden ser un constructor. En concreto, una variante se compone de una descripción de las características y los paquetes específicos de la variante.
  • El archivo de dependencias también se construye con el archivo de configuración para tener la posibilidad de elegir las versiones de los paquetes utilizados en la variante elegida.
  • Las variables de entorno intervienen justo antes de la construcción de la aplicación para especificar un determinado número de variables funcionales o técnicas. Ejemplo: El identificador de la variante o la url del servidor...

Gestión de rutas

Como se ha dicho antes, la segmentación implica la reunificación en un punto u otro. Si tomamos el ejemplo de los microservicios, la reunificación se realiza en la mayoría de los casos a través de una API-gateway para proporcionar un único punto de entrada a nuestra API. En nuestro caso, la reunificación implica el uso de enrutamiento con carga dinámica de interfaces de negocio (micro-aplicaciones gráficas) utilizando URLs.

Gestión de la configuración

Uno de los requisitos que se han planteado para justificar el uso de una arquitectura de microaplicaciones es la posibilidad de modular una aplicación en varias variantes. En efecto, esta arquitectura permite "construir" una aplicación diferente/personalizada para cada usuario.
La construcción de esta variante implica el uso de variables de entorno. Estas nos permiten dar parámetros de entrada en el momento de la construcción de nuestra aplicación. A partir de estas variables, somos capaces de construir nuestra aplicación con una determinada configuración.
Antes de la construcción y el uso de estas variables de entorno, se utiliza una herramienta de generación de código adicional para generar el archivo de dependencia y una clase de configuración. Estas dos últimas generaciones provienen del JSON archivo de configuración que describe estáticamente las micro-aplicaciones que se cargarán en la aplicación a través de las características.
Actualmente, este archivo se crea manualmente, pero esto implica muchos bloqueos técnicos y funcionales. En efecto, observamos, por ejemplo, la manipulación de las dependencias de las diferentes versiones o la compatibilidad desde el punto de vista funcional entre diferentes micro-aplicaciones. Esto nos lleva a la conclusión de que es necesario involucrar una herramienta de nivel superior para gestionar la generación del archivo de configuración (JSON que describe de forma estática las funcionalidades de las diferentes variantes).
Este expediente contempla varios elementos:

  • Todas las funciones disponibles
  • La definición de las microaplicaciones asociadas a las funcionalidades

Siguiendo estas generaciones, nuestro shell contiene una clase de configuración que representa todas las rutas disponibles en nuestra aplicación final.

Intercambio de información (contextualización)

Sin embargo, nuestra aplicación está, como hemos visto, segmentada en una multitud de micro-aplicaciones que no tienen ni idea del contexto en el que se utilizan. Por lo tanto, era necesario compartir esta configuración entre todos nuestros paquetes. Así, cualquier paquete tiene la posibilidad de referirse a un paquete de configuración que contiene la configuración de nuestra aplicación.
El valor añadido de este paquete es, por tanto, dar contexto a las microaplicaciones. Ejemplo: Una micro-app podría ver, editar y borrar datos. Sin embargo, la configuración nos informa de que la variante cargada no permite el borrado. El paquete de configuración nos permite acceder a esta información en cualquier parte de nuestra aplicación y especialmente en cualquier micro-app. Incluso si ésta se encuentra lejos en el árbol de navegación. Esto nos ahorra pasar la configuración a cada padre/hijo (Ver diagrama abajo: Figura 3).

Figura 4 - Diferencia en los métodos de inyección de dependencia

La gestión de los tipos/modelos dentro de la aplicación se realiza en dos partes. Nos fijamos en los modelos de negocio y en los modelos técnicos. Para gestionar mejor los DTOs, los modelos asociados a una lógica de negocio se colocan en la micro_app correspondiente. Sin embargo, los modelos más técnicos y puramente asociados a la gestión de la aplicación se proporcionan en un paquete separado que gestiona la configuración de nuestra aplicación.
Por lo tanto, cada paquete tiene la posibilidad de añadir contexto y enlace entre nuestros paquetes.

Ámbito de uso de los diferentes paquetes

Al crear una micro-aplicación asociada a un dominio de negocio o a un subdominio de negocio (operación particular sobre un dominio de negocio, por ejemplo), podemos ver esta última como una cáscara vacía que será alimentada internamente por la lógica de negocio (manejo de datos específicos del negocio, por ejemplo). Además, los paquetes externos independientes podrán proporcionar aplicaciones o funcionalidades técnicas adicionales a nuestra lógica de negocio.
Así, como puede verse en la FIG. 2, encontramos la lógica de negocio en el centro con una capa de aplicación que permite gestionar, entre otras cosas, los datos. En la periferia, el uso de paquetes externos permite reubicar las interfaces de usuario transversales y el código puramente técnico.

Implantación de la integración continua

La arquitectura de la microaplicación se ha diseñado como es la capacidad de ser modular, para tener la posibilidad de gestionar varias variantes de la misma aplicación. Este proceso de modularización se ha simplificado enormemente gracias a la integración continua. El proyecto presenta puntos de entrada como la variante elegida o la URL de nuestro backend. Pero podemos imaginarnos muy bien tener una multitud de variables de entrada. Con ellas se define una clase de configuración que enumera todas las variables de entrada. Esta clase es consumida por la aplicación para acceder al entorno de ejecución de la misma y así proporcionar la aplicación adecuada.
Así, con dos comandos, tenemos la posibilidad de elegir por ejemplo la variante de nuestra aplicación y optimizar la carga de las micro-aplicaciones. Lo que es interesante destacar aquí es esta capacidad de poder variar la aplicación antes de la compilación. Esto ha sido posible gracias al uso del paquete "environment_config" y al proyecto de generación de código. Las variables de entorno (de decisión) durante la integración continua provienen de un pipeline de integración continua y por lo tanto son fácilmente modificables.
Por último, la implementación de la integración continua se llevó a cabo utilizando la Forja y más particularmente de Gitlab CI / CD. Todo lo que se necesita es un YAML ". GitLab-ci.yml "para describir cómo vamos a modular nuestra aplicación y crear nuestro artefacto de salida. Una vez que la nueva versión de la aplicación empuja en una rama determinada (en nuestro caso "maestro"), se lanzará un script.
Como hemos visto anteriormente, en el caso de la elección de variantes, las variables de entorno tienen carácter decisorio y no descriptivo. De hecho, la descripción de la variante (su configuración) se realiza manualmente en el código o bien es generada por una herramienta de nivel superior que tendrá la capacidad de considerar los requisitos funcionales, por ejemplo. Por lo tanto, se recomienda, si tuviéramos que tener configuraciones algo complejas, utilizar las variables de entorno sólo para la toma de decisiones y declarar en el código o recuperar los objetos complejos.

Proceso de creación de una arquitectura de microaplicaciones

El eje principal en el que debemos fijarnos cuando queremos respetar una arquitectura de microaplicaciones es el aspecto empresarial. De hecho, nuestra arquitectura se basa en una arquitectura hexagonal (orientada al ámbito empresarial). Así pues, el primer paso es identificar los diferentes componentes empresariales que intervienen en la aplicación.
Los paquetes empresariales tienen la especificidad de manejar y presentar datos específicos de la lógica empresarial. Además, ésta debe ser lo más independiente posible de la lógica empresarial externa. Ocasionalmente, un paquete de negocio puede necesitar acceder a información de otro paquete de negocio. El objetivo no es reimplementar la forma de ir a buscar un componente de negocio. Es necesario pasar por el paquete de negocio para recuperar la información. Esto garantiza la integridad de los datos mientras se mantiene un código de negocio centralizado.
Es posible en la misma lógica de negocio desacoplar esta última en una multitud de paquetes de negocio. En efecto, una vez identificado el componente de negocio, podemos observar que se puede separar en varias funcionalidades. Podemos identificar, por ejemplo, un paquete de visualización y un paquete de edición de la lógica de negocio. Pueden dividirse porque no cumplen las mismas funciones.

Identificación de las interfaces transversales (funcionales y técnicas)

Durante el proceso de migración, es necesario identificar rápidamente la base técnica de la aplicación y los elementos que se reutilizan en varios o todos los paquetes empresariales. En efecto, podemos observar en la aplicación estudiada que tenemos un "núcleo" que representa la base técnica de la aplicación y más precisamente la configuración de la misma. Esta lógica se ha colocado en el nivel del paquete app_management (paquete ya presente en la arquitectura de referencia y esencial para la gestión de las configuraciones y el enrutamiento) porque se refiere a la lógica de la aplicación y debe ser accesible por todos los paquetes. También se pueden identificar o crear elementos (widgets) que se repiten en la aplicación. Podemos citar por ejemplo "entradas" con un estilo determinado, botones, etc...

Ejemplo de casos de uso

Durante el desarrollo de una aplicación, se pueden implementar varias funcionalidades como la geolocalización, el escaneo de QRCode o el establecimiento de una base de datos local. Para facilitar la identificación y el diseño de los paquetes, a continuación se presentan algunos ejemplos de características asociadas a un tipo de paquete.

Creación de una base de datos

Cuando es necesario para una aplicación que haya datos persistentes, hay que crear una base de datos local. Se tendería a instanciar una única base de datos común con un paquete que gestionara esa base de datos. Este paquete sería entonces un paquete técnico que cumpliría una función muy específica de acceso y disponibilidad de los datos.
Sin embargo, si intentamos establecer un paralelismo con los microservicios, podemos observar que la buena práctica es tener una base de datos por microservicio y, por tanto, lógicamente por lógica de negocio. Así, la configuración de una base de datos se realiza idealmente en el paquete de negocio asociado. Esto, una vez más, permite una única interfaz que accede y modifica los datos.

Geolocalización

La geolocalización es una función que puede ser utilizada por una multitud de paquetes porque no involucra a una empresa en su lógica. No necesita el contexto en el que se va a rendir la información a la función. Por lo tanto, podemos implementar esta funcionalidad utilizando un paquete funcional (funcionalidad transversal).

Gestión de la configuración y almacenamiento

Es habitual tener que almacenar datos de configuración relativos al funcionamiento de la aplicación o a las preferencias del usuario. Toda esta gestión debe encontrarse imperativamente en el paquete que gestiona las configuraciones y el enrutamiento de nuestra aplicación. El paquete "app_management" es un paquete esencial para el funcionamiento de nuestra futura aplicación y es posible añadir sus propias configuraciones.

Conclusión

La implementación de una arquitectura de micro-aplicaciones nos permitió destacar la posibilidad de modular o personalizar una aplicación a través de diferentes variantes. Y esto de la forma más sencilla posible con el uso de la integración continua. El hecho de segmentar nuestra aplicación para verla como un conjunto de ladrillos y no como un único bloque, nos permite abrir las puertas a la posibilidad de establecer un desarrollo por parte de un equipo de negocio que tendría que dar soporte a toda la cadena (desde el backend con su micro-servicio hasta el front end con su micro-aplicación).
Así, los mantenimientos y las evoluciones de nuestros productos se harán de forma optimizada y se centrarán en la funcionalidad a mantener o a evolucionar. Ya no nos preocuparemos de integrar una funcionalidad en una aplicación, sino de desarrollar una funcionalidad independiente y reutilizable en cualquier aplicación.
Todo ello para construir una pila de desarrollo común y mutualizada dentro de Berger-Levrault.

Listo para empezar con nuestro marco de micro-app, vaya a la forja : https://gitlab.forge.berger-levrault.com/bl-drit/flutter-micro-app-architecture

Más ...

Ir arriba