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:
- Identificar un bounded context dentro del sistema legacy
- Construir el nuevo servicio con funcionalidad equivalente
- Actualizar el enrutador para enviar trafico al nuevo servicio
- Validar que el nuevo servicio maneja trafico de produccion
- Repetir hasta reemplazar completamente el sistema legacy
- Desmantelar el sistema legacy
Variantes
| Variante | Enfoque | Ideal Para |
|---|---|---|
| API Gateway | Enrutar por prefijo de path | Migracion a microservicios |
| Servidor proxy | Reglas de rewrite de NGINX/Apache | Enrutamiento simple por URL |
| Feature toggle | Enrutamiento dinamico por solicitud | Migracion gradual de usuarios |
| Sync de base de datos | Dual-write durante transicion | Migracion 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.