Ir al contenido principal

Enrutamiento Dinámico y Avanzado con Amazon API Gateway: ¡Adiós a los Proxies!

Enrutamiento Dinámico y Avanzado con Amazon API Gateway: ¡Adiós a los Proxies!

En el mundo de las arquitecturas de microservicios, dirigir el tráfico de manera eficiente y flexible es un desafío constante. Tradicionalmente, esto implicaba configurar y mantener capas de proxy complejas o crear estructuras de URL enrevesadas. Sin embargo, Amazon API Gateway ha simplificado este proceso radicalmente con la introducción de las Reglas de Enrutamiento (Routing Rules), permitiendo un enrutamiento dinámico basado en cabeceras HTTP.

En este post, exploraremos cómo esta funcionalidad puede simplificar tu arquitectura, reducir la sobrecarga operativa y habilitar patrones de despliegue avanzados como Canary Releases y A/B Testing de forma nativa.


¿Qué son las Reglas de Enrutamiento?

Las Routing Rules son un recurso que se asocia a un dominio personalizado en API Gateway. Permiten desviar las solicitudes entrantes a diferentes integraciones de backend (como una etapa específica de una API REST) basándose en las condiciones que tú definas.

Cada regla se compone de tres elementos clave:

  • Condiciones (Conditions): Son los criterios que una solicitud debe cumplir. Puedes definir hasta dos condiciones basadas en cabeceras HTTP (headers) y una condición basada en la ruta base (base path).
  • Prioridad (Priority): Es un valor numérico que determina el orden de evaluación de las reglas. La regla con el número más bajo (empezando por 1) se evalúa primero.
  • Acción (Action): Define el destino de la solicitud si se cumplen las condiciones. Actualmente, la acción soportada es invocar una etapa de cualquier API REST dentro de la misma cuenta y región.

Modos de Enrutamiento: Flexibilidad Total

Para asegurar una transición suave y adaptarse a diferentes necesidades, API Gateway ofrece tres modos de enrutamiento en los dominios personalizados:

  • Solo mapeos de API (API mappings only): El comportamiento clásico y por defecto, donde el enrutamiento se basa únicamente en los mapeos de ruta base.
  • Reglas de enrutamiento y luego mapeos de API (Routing rules then API mappings): El modo más flexible. Primero se evalúan las reglas de enrutamiento. Si ninguna coincide, la solicitud se pasa a los mapeos de API tradicionales, que actúan como un fallback. Ideal para migraciones progresivas.
  • Solo reglas de enrutamiento (Routing rules only): Únicamente se utilizan las reglas de enrutamiento para dirigir el tráfico.

Ejemplos Prácticos de Enrutamiento Dinámico

La verdadera potencia de esta funcionalidad se aprecia en los casos de uso que habilita.

Ejemplo 1: Canary Release

Imagina que estás lanzando una nueva versión (v2) de tu API de "Productos". Quieres dirigir solo un 5% del tráfico a esta nueva versión para validarla en producción con un impacto limitado.

  • Paso 1: Despliegas tu v2 en una nueva etapa en API Gateway (ej. stage-v2).
  • Paso 2: Creas una regla de enrutamiento con alta prioridad.
    • Condición: Cabecera x-version es igual a v2.
    • Acción: Redirigir a la API de Productos en la etapa stage-v2.
  • Paso 3: La lógica de tu balanceador de carga o capa de cliente se encarga de inyectar la cabecera x-version: v2 en el 5% de las solicitudes. El 95% restante, al no tener esa cabecera, será dirigido a la versión estable (v1) por una regla de menor prioridad o por el mapeo de API de fallback.

Ejemplo 2: A/B Testing para una Nueva Feature

Quieres probar una nueva funcionalidad de "Recomendaciones Personalizadas" con un grupo selecto de usuarios beta.

  • Paso 1: Despliegas la nueva funcionalidad en una etapa separada (ej. stage-beta-features).
  • Paso 2: Creas una regla de enrutamiento.
    • Condición: Cabecera x-user-group es igual a beta-testers.
    • Acción: Redirigir a la API con la nueva feature en la etapa stage-beta-features.
  • Paso 3: Tu aplicación cliente añade la cabecera x-user-group: beta-testers a las solicitudes de los usuarios que participan en la prueba. El resto de los usuarios no enviará esta cabecera y será dirigido a la versión estándar de la aplicación.

Ejemplo de Código CDK (TypeScript)

A continuación se muestra un ejemplo de cómo implementar un enrutamiento dinámico para un *Canary Release* usando AWS CDK. En este escenario, el tráfico con la cabecera x-version: v2 se dirige a la etapa `v2` de la API, mientras que el resto del tráfico va a la etapa `v1`.


import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class DynamicRoutingStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Asume que tienes un certificado y un dominio personalizado
    const domainName = 'api.tudominio.com';
    const certificate = acm.Certificate.fromCertificateArn(this, 'Cert', 'arn:aws:acm:us-east-1:ACCOUNT_ID:certificate/CERTIFICATE_ID');

    // 1. Crea una API REST y una función Lambda de ejemplo
    const handler = new lambda.Function(this, 'MyLambda', {
      runtime: lambda.Runtime.NODEJS_20_X,
      code: lambda.Code.fromInline('exports.handler = async () => ({ statusCode: 200, body: "Hello from Lambda!" });'),
      handler: 'index.handler',
    });

    const api = new apigateway.LambdaRestApi(this, 'MyApi', {
      handler,
      proxy: false,
    });
    
    // Agrega un recurso y método a la API
    const resource = api.root.addResource('items');
    resource.addMethod('GET');

    // 2. Crea dos etapas (stages) para la misma API
    const stageV1 = new apigateway.Stage(this, 'V1Stage', { deployment: api.latestDeployment!, stageName: 'v1' });
    const stageV2 = new apigateway.Stage(this, 'V2Stage', { deployment: api.latestDeployment!, stageName: 'v2' });

    // 3. Define la configuración de enrutamiento usando el constructo L1 (CfnDomainName)
    const apiDomain = new apigateway.CfnDomainName(this, 'ApiDomain', {
      domainName,
      certificateArn: certificate.certificateArn,
      endpointConfiguration: {
        types: ['REGIONAL'],
      },
      // Configuración clave para el enrutamiento dinámico
      routingConfig: {
        routingMode: 'ROUTING_RULES_THEN_API_MAPPINGS',
        rules: [
          {
            // Regla para la versión v2 (Canary)
            priority: 1,
            conditions: [
              {
                header: { name: 'x-version', value: 'v2' },
              },
            ],
            // Acción: invocar la etapa v2
            stageArn: stageV2.stageArn,
          },
        ],
      },
    });

    // 4. Crea el mapeo de API base (fallback) para la versión v1
    new apigateway.CfnApiMapping(this, 'ApiMappingV1', {
      apiId: api.restApiId,
      domainName: apiDomain.domainName,
      stage: stageV1.stageName,
    });
  }
}

Observabilidad y Monitoreo

Para tener visibilidad completa del comportamiento de tus reglas, API Gateway ha enriquecido sus registros de acceso (access logs). Se han añadido nuevas variables de contexto que te permiten saber exactamente qué regla coincidió con una solicitud y por qué, facilitando enormemente la depuración y el monitoreo del flujo de tráfico.


Conclusión

El enrutamiento dinámico basado en reglas de Amazon API Gateway es una herramienta poderosa que simplifica la arquitectura de tus aplicaciones, eliminando la necesidad de capas de proxy intermedias y lógicas de enrutamiento complejas en el cliente. Permite implementar patrones de despliegue modernos de forma declarativa, segura y escalable, acelerando la innovación y mejorando la resiliencia de tus servicios. Y lo mejor de todo: no tiene un costo adicional. Es una funcionalidad nativa que ya puedes empezar a utilizar en tus REST APIs públicas y privadas.


Fuentes

Entradas populares de este blog

Event Driven Architecture & Big ball of mud

EDA Una arquitectura event-driven (EDA) es un estilo de diseño que se basa en la producción, detección y reacción a eventos. Un evento es un cambio de estado significativo en el sistema o en el entorno que puede ser notificado a otros componentes interesados. Una arquitectura event-driven permite una mayor desacoplamiento, escalabilidad y resiliencia entre los componentes del sistema, así como una mejor adaptabilidad a los cambios y a las necesidades del negocio. Sin embargo, una arquitectura event-driven también puede tener sus desafíos y riesgos, especialmente si no se aplica una buena gestión de los dominios y los boundaries. Un dominio es un conjunto de conceptos, reglas y procesos relacionados con un aspecto del negocio o del problema que se quiere resolver. Un boundary es una frontera lógica que separa y protege un dominio de otros dominios o de influencias externas. Un buen diseño de dominios y boundaries facilita la comprensión, el mantenimiento y la evolución del sistema, así ...

¿Qué es el patrón Circuit Breaker y cómo se puede implementar con AWS Step Functions?

En el desarrollo de software, es común que las aplicaciones se comuniquen con servicios o recursos externos, como bases de datos, APIs o microservicios. Sin embargo, estos servicios o recursos pueden fallar o estar temporalmente indisponibles por diversas razones, lo que puede afectar el rendimiento y la disponibilidad de la aplicación. Para manejar estos escenarios de falla, se puede utilizar el patrón Circuit Breaker, que consiste en detectar y prevenir que una operación que tiene alta probabilidad de fallar se ejecute repetidamente, causando más problemas o consumiendo recursos innecesarios.  El patrón Circuit Breaker tiene tres estados posibles: cerrado, abierto y medio abierto. Cerrado : En este estado, el circuito está funcionando normalmente y la operación se ejecuta sin problemas. Si se detecta una falla, se incrementa un contador de fallas y se calcula un umbral de fallas, que puede ser un número o un porcentaje de fallas permitidas. Si el contador de fallas supera el u...

¿Cómo usar Lambda con Amazon SQS para procesar mensajes de forma asíncrona y escalable?

Amazon Simple Queue Service (Amazon SQS) es un servicio de colas de mensajes que permite enviar y recibir mensajes entre componentes de una aplicación de forma fiable y duradera. Con Amazon SQS, se puede desacoplar la lógica de negocio de la fuente de los eventos, y procesarlos de forma asíncrona y en paralelo.   En este artículo, vamos a ver cómo usar Lambda con Amazon SQS para procesar mensajes de una cola de forma eficiente y flexible, aprovechando las características de concurrencia, escalamiento y procesamiento del event source mapping de Lambda, así como la estrategia de backoff que implementa Lambda para manejar errores y reintentos.   Concurrencia del event source mapping Un event source mapping es una configuración que le dice a Lambda qué fuente de eventos debe monitorear y qué función debe invocar cuando se produzca un evento. En el caso de Amazon SQS, el event source mapping se encarga de leer los mensajes de la cola y enviarlos a la función Lambda en lotes. La con...