Implementa una arquitectura hexagonal para aplicaciones serverless en menos de 10 minutos
En este artículo, profundizaremos en cómo la arquitectura hexagonal puede transformar tus aplicaciones serverless de AWS. Exploraremos los conceptos principales, descubriremos las ventajas y veremos un ejemplo práctico que muestra la arquitectura hexagonal en acción.
Published Feb 21, 2024
Bienvenido al mundo en el que las aplicaciones serverless se unen a los poderes de la arquitectura hexagonal. Cuando hablamos de aplicaciones serverless, todos conocemos sus ventajas: no hay gestión de servidores, es rentable y su escalabilidad, lo que parece casi mágico. Pero incluso en este país de las maravillas, ¿cómo nos aseguramos de que nuestras aplicaciones no solo son escalables sino también resilientes y fáciles de mantener? Es justo acá en donde entra la arquitectura hexagonal, nuestro caballero de brillante armadura.
La arquitectura hexagonal, también conocida como patrón de puertos y adaptadores, no es solo otra palabra de moda que se utiliza en las reuniones técnicas. Es un enfoque estratégico del diseño de aplicaciones que cambia radicalmente la forma en que creamos, probamos y pensamos sobre nuestras aplicaciones. Al hacer hincapié en la separación de las preocupaciones, se garantiza que nuestra lógica de negocio no se vea afectada por los cambios externos, lo que hace que nuestras aplicaciones sean tanto resilientes como escalables.
En este artículo, profundizaremos en cómo la arquitectura hexagonal puede transformar tus aplicaciones serverless de AWS. Exploraremos los conceptos principales, descubriremos las ventajas y veremos un ejemplo práctico que muestra la arquitectura hexagonal en acción. Escoge tu IDE de Python favorito, yo usé Visual code 🙂 y empecemos el viaje hacia el éxito de las aplicaciones serverless.
Si alguna vez te has perdido entre código espagueti que mezcla la lógica de negocio con la interfaz de usuario y el acceso a las bases de datos, no estás solo. Este es el mismo laberinto del que la arquitectura hexagonal pretende salvarnos. Pero, ¿qué es exactamente esta arquitectura y por qué parece que pertenece más a una clase de geometría que al desarrollo de aplicaciones?
En esencia, la arquitectura hexagonal es un patrón que promueve la separación de la lógica central de una aplicación de sus interacciones externas. Piensa en tu aplicación como el centro de un hexágono. Cada lado del hexágono representa un puerto que interactúa con el mundo exterior a través de un adaptador. Estos puertos pueden ser para una interfaz web, una base de datos o incluso un guion de prueba. Lo mejor de este diseño es que permite hacer cambios en cualquier componente externo como cambiar una base de datos o cambiar la interfaz de usuario sin tener que reescribir la lógica de negocio.
- Separación de preocupaciones: Al mantener aislada la lógica principal de la aplicación, los desarrolladores pueden centrarse en las reglas de negocio sin quedar enredados en dependencias externas. (La parte del dominio que aparece en la imagen de arriba)
- Independencia de componentes externos: Los adaptadores facilitan el cambio de la forma en que la aplicación interactúa con el mundo exterior, lo que facilita las pruebas y la evolución. (La pieza del adaptador que aparece en la imagen de arriba)
- Simplicidad: A pesar del nombre que suena complejo, la arquitectura hexagonal simplifica el desarrollo y el mantenimiento de las aplicaciones al delinear claramente las responsabilidades.
Las arquitecturas tradicionales, como la arquitectura por capas o monolito, suelen combinar la lógica de negocio con las capas de acceso y presentación a los datos, lo que dificulta modificar o escalar un aspecto sin afectar a los demás. La arquitectura hexagonal, por otro lado, trata estas interacciones como componentes listos para usar que se pueden reemplazar o actualizar fácilmente sin interrumpir la funcionalidad principal.
- Capacidad de prueba mejorada: Con la lógica de negocio desvinculada de los componentes externos, las pruebas son muy fáciles. Puedes utilizar adaptadores simulados para tus puertos, lo que permite realizar pruebas unitarias exhaustivas y aisladas.
- Flexibilidad en el desarrollo y el despliegue: ¿Quieres pasar de una base de datos monolítica a microservicios? ¿O quizás cambiar tu interfaz de usuario de una plataforma web a una móvil? La arquitectura hexagonal facilita estas transiciones sin necesidad de revisar el núcleo de la aplicación.
- Mantenimiento y escalabilidad más sencillos: A medida que tu aplicación crezca, mantener una separación limpia entre la lógica principal y las interfaces externas significa que puedes escalar o actualizar partes de tu sistema de forma independiente. Este estilo arquitectónico conduce naturalmente a aplicaciones más escalables y fáciles de mantener.
En esencia, la arquitectura hexagonal no consiste solo en mantener tu base de código limpia y ordenada, sino que es un enfoque estratégico para crear software que esté preparado para evolucionar con tus necesidades. Al adoptar este patrón, los desarrolladores pueden asegurarse de que sus aplicaciones son sólidas, adaptables y preparadas para el futuro, sin importar cómo cambie el panorama tecnológico.
Las aplicaciones serveless han agregado un punto de inflexión tanto para los desarrolladores como para las empresas, ya que ofrece la posibilidad de crear e implementar aplicaciones sin la molestia de gestionar los servidores. AWS, con su completa gama de servicios serverless, ha estado a la vanguardia de esta revolución. Pero un gran poder conlleva una gran responsabilidad, la responsabilidad de diseñar aplicaciones que no solo sean escalables sino también resilientes y fáciles de mantener. Aquí es donde brilla la arquitectura hexagonal.
La arquitectura serverless promueve la idea de crear aplicaciones como un conjunto de funciones que responden a los eventos. Este modelo complementa de forma natural el énfasis de la arquitectura hexagonal en la separación de preocupaciones y la adaptabilidad:
- Desacoplamiento: Así como las funciones serverless se desacoplan de la infraestructura subyacente, la arquitectura hexagonal desacopla la lógica de las aplicaciones de sus interacciones externas. Esta sinergia permite aplicaciones más resilientes y flexibles que pueden adaptarse fácilmente a los cambios en el entorno o los requisitos.
- Event-Driven: La arquitectura serverless se basa intrínsecamente en los eventos, y la arquitectura hexagonal lo apoya al tratar las interacciones con el mundo exterior como eventos que llegan a través de puertos. Esto facilita el diseño de aplicaciones que reaccionen a una variedad de activadores, desde solicitudes HTTP hasta actualizaciones de bases de datos.
- Flexibilidad: La arquitectura hexagonal permite cambiar fácilmente los componentes e interfaces externos. En un contexto serverless, esto significa que puedes cambiar tu almacenamiento de datos de DynamoDB a otro servicio o modificar la configuración de tu API Gateway sin necesidad de reescribir tu lógica de negocio. Esta flexibilidad tiene un valor incalculable en un ecosistema de nube acelerado y en constante cambio.
- Escalabilidad: Las arquitecturas serverless son excelentes a la hora de escalar automáticamente en respuesta a la demanda. La arquitectura hexagonal complementa esto al garantizar que la lógica principal de la aplicación permanece aislada y no se ve afectada por las operaciones de escalado. Este aislamiento significa que, a medida que AWS aumenta o reduce tus funciones, la integridad de la lógica de tu aplicación permanece intacta, libre de las complejidades de escalabilidad de la infraestructura.
- Mantenibilidad: Los límites claros establecidos por la arquitectura hexagonal facilitan el mantenimiento y la actualización de las aplicaciones serverless. Como la lógica empresarial está desacoplada de las interfaces externas, a menudo se pueden aplicar actualizaciones o correcciones a los adaptadores sin afectar a la aplicación principal. Esta separación simplifica las tareas de mantenimiento y reduce el riesgo de introducir errores en la lógica principal durante las actualizaciones.
La adopción de una arquitectura hexagonal en las aplicaciones serverless no solo aborda los desafíos actuales de diseño y escalabilidad, sino también abre la puerta a la innovación futura. Permite a los equipos experimentar con nuevos servicios de AWS o integraciones de terceros con un riesgo mínimo para la aplicación existente. Ya sea que se trate de integrar un nuevo servicio de notificaciones o de experimentar con diferentes tecnologías de bases de datos, la arquitectura hexagonal garantiza que tu aplicación serverless siga siendo sólida y adaptable.
En resumen, la arquitectura hexagonal y serverless forman un dúo poderoso. Juntos, proporcionan un marco para crear aplicaciones que no solo sean escalables y rentables, sino también resilientes, adaptables y fáciles de mantener.
Cuando escuches por primera vez «Arquitectura hexagonal» en el contexto de AWS Serverless y Python, puede parecer que estamos a punto de realizar algún ritual arcano. Pero, en realidad, se parece más a organizar tus bloques de LEGO digitales de manera que sea más fácil jugar con ellos, cambiarlos y probarlos sin pisarlos en mitad de la noche.
Antes de ensuciarnos las manos, veamos nuestras herramientas. Servicios como AWS Lambda para ejecutar nuestro código sin aprovisionar servidores, Amazon API Gateway para gestionar las solicitudes HTTP, y Amazon DynamoDB para una base de datos NoSQL totalmente gestionada. Estos son nuestros pilares y van a desempeñar un papel importante como «puertos» en nuestro mundo hexagonal.
La esencia de la arquitectura hexagonal es desglosar tu aplicación en una separación clara de las preocupaciones. Tienes la lógica de tu aplicación principal, el corazón y el alma de tu operación. Aquí es donde reside tu lógica de negocio, escrita en Python, tomando decisiones, procesando datos y, en general, siendo inteligente. Tu aplicación se encuentra a salvo del caos del mundo exterior.
Luego, alrededor de este núcleo, tenemos puertos y adaptadores. Los puertos son los puntos predefinidos de tu aplicación a los que se pueden conectar los servicios externos (como bases de datos, colas de mensajes o servicios de correo electrónico). Los adaptadores son los traductores, escritos en Python, que convierten las llamadas externas al formato que entiende tu lógica básica y viceversa.
Imagina que estamos creando un sistema para gestionar el registro de los usuarios en un nuevo servicio. Nuestra lógica principal incluye funciones para validar los datos de los usuarios, crear nuevos registros de usuarios y enviar correos electrónicos de bienvenida. Así es como podemos organizar esto con Hexagonal Architecture:
- Dominio principal (lógica de aplicación): Una función de Python «register_user» que tomará los datos del usuario, los valida y, si todo está bien, los prepara para su almacenamiento y envío de notificaciones.
- Puerto de almacenamiento de usuario: Decidimos que DynamoDB es nuestra solución de almacenamiento. El puerto aquí es la acción abstracta de guardar a un usuario.
- Adaptador para DynamoDB: Una función de Python que toma los datos de usuario de la lógica de negocio y sabe cómo insertarlos en DynamoDB. Este adaptador habla Python (el lenguaje de nuestra aplicación) y las llamadas a la API de DynamoDB.
- Puerto para enviar correos electrónicos: Se define otro puerto para enviar correos electrónicos de bienvenida a los nuevos usuarios.
- Adaptador para AWS SES (servicio simple de correo electrónico): Una función de Python que toma las instrucciones para enviar un correo electrónico de bienvenida y las traduce en una llamada de API a SES, con el contenido del correo electrónico, el destinatario y otros detalles.
Esta estructura permite que la lógica principal de nuestra aplicación no sepa qué base de datos o servicio de correo electrónico utilizamos. Si decidimos cambiar de DynamoDB a otra base de datos, solo necesitamos reemplazar el adaptador, no reescribir la lógica principal.
Analicemos el sencillo ejemplo de implementación de la arquitectura hexagonal en una aplicación serverless de AWS con Python en una guía paso a paso.
- Crea una tabla de DynamoDB: Inicia sesión en tu consola de AWS, ve al servicio DynamoDB y crea una nueva tabla llamada «Usuarios». Para la clave principal, usa «UserID» de tipo String.
- Configurar AWS SES: Asegúrate de que AWS SES está configurado y verificado en tu cuenta de AWS. Necesitarás una dirección de correo electrónico verificada desde la que enviar correos de bienvenida a los nuevos usuarios.
- Crea una función de Python para el registro de usuarios: Esta función ('register_user') recogerá los datos del usuario (por ejemplo, el nombre o el correo electrónico) y procederá a guardar al usuario y le enviará un correo electrónico de bienvenida.
- Adaptador DynamoDB para almacenamiento de usuarios:
- Adaptador SES para enviar correos electrónicos:
- Lambda para el registro de usuarios: configura una nueva función de AWS Lambda que utilice el tiempo de ejecución de Python. Usa el código que has preparado para «register_user», incluidos los adaptadores. Esta función se activará mediante un evento de API Gateway o directamente a través de la consola de AWS con fines de prueba.
- Pruebas unitarias: escribe pruebas unitarias para tu función «register_user» utilizando Mock data de las funciones «save_user» y «send_welcome_email». Esto garantiza que tu lógica principal funcione como se esperaba sin necesidad de interactuar realmente con DynamoDB o SES.
- Pruebas de integración: prueba todo el flujo invocando tu función Lambda con una carga útil de datos de usuario de ejemplo. Comprueba que los datos están guardados en DynamoDB y que se ha enviado un correo electrónico de bienvenida.
- Despliegue: una vez que las pruebas sean satisfactorias, implementa tu función Lambda y expóntela a través de API Gateway si quieres activar el registro de usuarios mediante solicitudes HTTP.
- Observabilidad: Usa AWS CloudWatch para revisar los registros de tu función Lambda y asegurarte de que todo funciona sin problemas.
¡Felicidades! 🎉 Ya has implementado un sistema sencillo de registro de usuarios mediante la arquitectura hexagonal en AWS Serverless con Python. Esta arquitectura hace que tu aplicación sea más resiliente y adaptable, lo que te permite reemplazar los componentes fácilmente sin afectar a la lógica principal.
Recuerda que la clave del éxito de una Arquitectura Hexagonal es una separación clara de las preocupaciones y el uso adecuado de los adaptadores para comunicarse con los servicios externos. ¡Happy Coding!