Skip to content
SP StackPractices
intermediate Por StackPractices

Patron de Higuera Estranguladora

Migra funcionalidad incrementalmente desde un sistema legacy hacia uno nuevo interceptando llamadas y enrutandolas, reemplazando eventualmente el sistema viejo por completo.

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Patron de Higuera Estranguladora

Resumen

El Patron de Higuera Estranguladora permite migrar funcionalidad desde un sistema legacy hacia uno nuevo de forma incremental. Una capa intermediaria intercepta solicitudes y las enruta al sistema legacy o al nuevo.

Con el tiempo, a medida que mas funcionalidades migran, el sistema legacy se reduce hasta poder desmantelarse por completo.

Cuando Usar

  • Migrar de monolito legacy a microservicios
  • Reemplazar stack tecnologico sin rewrite riesgoso
  • Modernizar un sistema con requisitos en evolucion
  • Entregar nuevas funcionalidades en el sistema nuevo mientras se mantiene el legacy

Cuando Evitar

  • Sistema legacy pequeno para reemplazo directo
  • Equipo sin capacidad de mantener ambos sistemas
  • Latencia de red de una capa de enrutamiento inaceptable

Solucion

Python (Flask Proxy)

from flask import Flask, request, jsonify
import requests
import os

class StranglerRouter:
    def __init__(self):
        self.legacy = os.getenv('LEGACY_API', 'http://legacy:8080')
        self.new = os.getenv('NEW_API', 'http://new-service:8080')
        self.routes = {
            '/api/users': 'new',
            '/api/orders': 'new',
            '/api/inventory': 'legacy',
        }

    def route(self, path, method, data=None):
        target = self.routes.get(path, 'legacy')
        base = self.new if target == 'new' else self.legacy
        response = requests.request(method, f"{base}{path}", json=data)
        return response.json(), response.status_code

app = Flask(__name__)
router = StranglerRouter()

@app.route('/api/<path:path>')
def gateway(path):
    body, status = router.route(f"/api/{path}", request.method,
                                request.get_json() if request.is_json else None)
    return jsonify(body), status

Java (Spring Cloud Gateway)

@Configuration
public class StranglerGatewayConfig {
    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("users", r -> r.path("/api/users/**")
                .uri("http://new-users-service:8080"))
            .route("legacy", r -> r.path("/**")
                .uri("http://legacy-system:8080"))
            .build();
    }
}

JavaScript (Express Proxy)

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();

app.use('/api/users', createProxyMiddleware({
    target: 'http://new-users-service:8080', changeOrigin: true }));
app.use('/', createProxyMiddleware({
    target: 'http://legacy-system:8080', changeOrigin: true }));
app.listen(3000);

Explicacion

La capa intermediaria enruta solicitudes:

  1. Identificar un bounded context dentro del sistema legacy
  2. Construir el nuevo servicio con funcionalidad equivalente
  3. Actualizar el enrutador para enviar trafico al nuevo servicio
  4. Validar que el nuevo servicio maneja trafico de produccion
  5. Repetir hasta reemplazar completamente el sistema legacy
  6. Desmantelar el sistema legacy

Variantes

VarianteEnfoqueIdeal Para
API GatewayEnrutar por prefijo de pathMigracion a microservicios
Servidor proxyReglas de rewrite de NGINX/ApacheEnrutamiento simple por URL
Feature toggleEnrutamiento dinamico por solicitudMigracion gradual de usuarios
Sync de base de datosDual-write durante transicionMigracion de capa de datos

Mejores Practicas

  • Empezar con endpoints de solo lectura de bajo riesgo
  • Implementar trafico shadow para comparar respuestas
  • Mantener compatibilidad hacia atras en APIs
  • Monitorear ambos sistemas durante la transicion
  • Mantener capacidad de rollback

Errores Comunes

  • Migrar demasiado sin validacion
  • No monitorear el nuevo sistema bajo carga
  • Romper contratos de datos entre sistemas
  • Eliminar legacy antes de que el nuevo sistema este operativo

Ejemplos del Mundo Real

  • Amazon: Famoso por migrar de monolito C++ a arquitectura orientada a servicios usando wrappers y proxies.
  • UK Government Digital Service: GOV.UK se construyo junto a sitios gubernamentales existentes, reemplazandolos dominio por dominio.

Preguntas Frecuentes

P: ¿Cuanto dura una migracion con este patron? R: Meses a años. Lo clave es que el sistema es funcional y mejora durante todo el proceso.

P: ¿Que pasa si legacy y nuevo usan diferentes bases de datos? R: Implementar una capa anticorrupcion y considerar estrategias de dual-write durante la transicion.

P: ¿Puedo usar esto para migracion frontend? R: Si — enrutar paginas o componentes a nuevas implementaciones manteniendo el shell de la app vieja.