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

Python 3.14 y el Fin del GIL: Explorando Oportunidades y Desafíos

Python 3.14 y el Fin del GIL: Explorando Oportunidades y Desafíos La versión 3.14 de Python ha generado gran expectativa, principalmente por la implementación de mejoras significativas, entre las que destacan: Sub-intérpretes: Disponibles en Python durante dos décadas, pero limitados al uso de código C. Ahora se pueden emplear directamente desde Python. T-Strings: Un nuevo método para el procesamiento personalizado de cadenas, con una sintaxis similar a los f-strings , pero que devuelve un objeto que representa tanto las partes estáticas como las interpoladas de la cadena. Compilador Just-In-Time (JIT): Aunque aún experimental, esta característica promete mejorar el rendimiento en casos de uso específicos. Sin embargo, el aspecto más relevante de esta versión es la introducción de Python con hilos libres , también conocido como Python sin GIL . Es importante señalar que la versión estándar de Python 3.14 seguirá utilizando el GIL, pero se puede descargar (o construir) u...

¿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...