Contenido
En entregas anteriores de esta serie, exploramos pasos fundamentales para establecer un proyecto serverless, incluyendo la configuración de un entorno de desarrollo con herramientas de emulación y el esquema de una arquitectura general multinivel. Este segmento se centra en implementar patrones de diseño adaptados al desarrollo de un sistema serverless que se adhiera al paradigma Function as a Microservice (FaaM). \n\nLa cuestión de la granularidad del servicio ha evolucionado junto con la historia de la computación distribuida. En las décadas de 1970 y 80, surgieron enfoques tempranos de integración como Remote Procedure Calls (RPC), CORBA y Distributed Computing Environment (DCE), pero a menudo tenían limitaciones en escalabilidad y flexibilidad para entornos híbridos. A mediados de los 90 se marcó un punto de inflexión con la aparición de la Arquitectura Orientada a Servicios (SOA), que ganó prominencia a principios de los 2000 mediante implementaciones basadas en SOAP. SOA revolucionó el diseño de software al permitir servicios débilmente acoplados. La evolución continuó en la década de 2010 con REST, arquitecturas orientadas a eventos (EDA) y microservicios, pero persiste un desafío: determinar el tamaño y alcance ideal de un servicio.\n\nHistóricamente, SOA definió dos tipos principales de granularidad de servicio: gruesa y fina. Los servicios gruesos abarcan amplias capacidades de negocio, mientras que los servicios finos se centran en funciones de alcance estrecho. Ambos extremos presentan desafíos; los servicios gruesos grandes corren el riesgo de convertirse en "monolitos" inmanejables, mientras que los servicios finos pueden producir un número abrumador de componentes pequeños e interdependientes, complicando la escalabilidad, modificabilidad y seguridad. El Service-Oriented Modeling Framework (SOMF) ofrece categorías matizadas: los servicios atómicos son componentes básicos e indivisibles con procesos limitados; los servicios compuestos agregan servicios atómicos u otros compuestos en estructuras jerárquicas; y los clústeres son grupos de servicios relacionados que colaboran hacia soluciones más amplias.\n\nTraducir estos conceptos al ámbito de la computación serverless con Serverless Framework y AWS Lambda implica entender tres constructos centrales: Eventos, Funciones y Servicios. Los eventos disparan funciones, que ejecutan fragmentos discretos de código realizando tareas específicas. Los servicios encapsulan grupos de funciones Lambda junto con sus eventos disparadores y requisitos de infraestructura. El Serverless Framework típicamente recomienda crear funciones Lambda individuales para cada operación CRUD, lo que implica que una entidad como Usuario podría corresponder a cuatro funciones Lambda. Aunque sencillo, este enfoque escala mal: diez entidades conducen a 40 funciones, cada una requiriendo gestión y asociada a instancias separadas de AWS API Gateway, aumentando la sobrecarga operativa.\n\nPara abordar esta complejidad, se propone el patrón Function as a Microservice (FaaM). Aquí, cada función Lambda actúa como un pequeño clúster, manejando múltiples capacidades de negocio relacionadas y enroutando internamente varios eventos atómicos. Por ejemplo, en lugar de una función por operación de ciudad, una función de geolocalización gestiona operaciones CRUD para países, ciudades y regiones colectivamente. Para evitar la hinchazón monolítica, cada función debería manejar idealmente no más de 7±2 entidades, en línea con los límites cognitivos descritos por la Ley de Miller. Este diseño asume que cada función mantiene la responsabilidad exclusiva de su fuente de datos específica.\n\nImplementar FaaM dentro de AWS Lambda requiere mecanismos de enrutamiento eficientes, dado que cada función Lambda tiene un único manejador de entrada. Un patrón Cliente-Despachador-Servidor puede facilitar esto dirigiendo las solicitudes entrantes según sus rutas URI. Por ejemplo, una solicitud HTTP a /movie debería enrutar a la función relevante que maneja operaciones relacionadas con películas. Usando este patrón, múltiples servicios lógicos —como usuarios, geolocalización y publicaciones— pueden compartir el mismo código manejador pero diferenciar el procesamiento internamente mediante enrutamiento. Este enfoque reduce el número de funciones Lambda y puntos finales de API Gateway, simplificando la gestión mientras preserva límites claros del dominio de negocio.\n\nEn la práctica, la configuración del Serverless Framework podría definir varios servicios con múltiples eventos HTTP apuntando al mismo manejador —por ejemplo, endpoints de login, logout y signup bajo usuarios, varios endpoints de ubicación bajo geolocalización, y operaciones CRUD para películas bajo publicaciones. La lógica de enrutamiento dentro del manejador compartido inspecciona la URI y el método del evento para invocar el módulo de lógica de negocio apropiado. Esta estrategia mejora la mantenibilidad al evitar código repetitivo en manejadores y permite un crecimiento modular dentro de arquitecturas serverless.