Blog

Arquitecturas de datos: cómo versionar el esquema cuando el pipeline depende de APIs externas

28 de agosto de 2026 · Equipo FeedScale

Arquitecturas de datos: cómo versionar el esquema cuando el pipeline depende de APIs externas

El pipeline lleva semanas estable. Entonces el proveedor de datos publica una nota técnica discreta: "ajuste menor en el formato de respuesta, sin impacto previsto". Cuarenta y ocho horas después el job de transformación empieza a emitir errores silenciosos. Los registros siguen entrando, pero un campo ha cambiado de tipo string a array. El modelo de downstream lo interpreta como nulo. Nadie lo detecta hasta que alguien pregunta por qué las métricas de cobertura llevan dos días en cero.

Este escenario no es excepcional. Es el modo por defecto en entornos donde el esquema de la API externa no está bajo tu control. Y el problema no es que el proveedor cambie el esquema —lo hará— sino que la arquitectura no tiene una estrategia de versionado que absorba ese cambio sin romper producción.

Versionar el esquema propio es higiene básica. Versionar el esquema ajeno que recibes por API es ingeniería defensiva. Son disciplinas distintas y la segunda se ignora con mucha más frecuencia.

El error de tratar el esquema externo como estático

Muchos equipos diseñan el pipeline asumiendo que el contrato de datos del proveedor es una constante. Mapean los campos en el primer sprint, los hardcodean en el transformador y pasan al siguiente problema. Funciona durante meses. Entonces falla.

El fallo no llega siempre como una excepción visible. A veces llega como silencio: un campo que desaparece devuelve null y el pipeline sigue procesando sin quejarse. El dato incompleto viaja hasta el data warehouse. El analista lo descubre tres semanas después cuando intenta cruzar ese campo con otra fuente.

La raíz del problema es arquitectónica: no existe una capa que observe el esquema entrante, lo compare con la versión conocida y decida cómo actuar. Todo el sistema asume que el contrato es inmutable.

Diseñar una capa de validación de esquema en la ingestión

La solución empieza antes de transformar: validar el esquema en el punto de entrada, no en el destino.

El patrón más efectivo es mantener un schema registry propio, independiente del proveedor, donde se almacena la versión canónica esperada de cada respuesta API. Cada vez que llega un payload, se valida contra esa versión antes de que el dato entre al pipeline.

import jsonschema
import json

SCHEMA_REGISTRY = {
    "feed_response_v3": {
        "type": "object",
        "required": ["id", "published_at", "source", "sentiment_score"],
        "properties": {
            "id": {"type": "string"},
            "published_at": {"type": "string", "format": "date-time"},
            "source": {"type": "object"},
            "sentiment_score": {"type": "number"}
        }
    }
}

def validate_payload(payload: dict, schema_key: str) -> bool:
    try:
        jsonschema.validate(instance=payload, schema=SCHEMA_REGISTRY[schema_key])
        return True
    except jsonschema.ValidationError as e:
        log_schema_drift(schema_key, str(e))
        return False

Cuando la validación falla, el payload no se descarta automáticamente: se enruta a una dead-letter queue con metadatos del error. El pipeline principal sigue funcionando. El equipo recibe una alerta y tiene tiempo de analizar el drift antes de decidir si actualiza el schema registry o implementa una capa de compatibilidad.

Schema evolution: compatibilidad hacia atrás y hacia adelante

No todos los cambios de esquema rompen el pipeline de la misma manera. Conviene clasificarlos antes de reaccionar:

Cambios compatibles hacia atrás (el código existente sigue funcionando):

Cambios incompatibles (rompen el código existente):

El schema registry debe almacenar todas las versiones históricas, no solo la última. Así el pipeline puede activar un modo de compatibilidad cuando detecta que el payload entrante corresponde a una versión anterior conocida, en lugar de rechazarlo directamente.

def detect_schema_version(payload: dict) -> str:
    # Heurística simple: presencia de campos discriminadores
    if "sentiment_score" in payload and isinstance(payload["sentiment_score"], list):
        return "feed_response_v4"
    elif "sentiment_score" in payload:
        return "feed_response_v3"
    return "feed_response_unknown"

Este enfoque permite mantener varios transformadores activos en paralelo —uno por versión— y enrutar cada payload al transformador correcto sin detener la ingestión.

Alertas de drift: monitorizar la desviación antes de que llegue el error

La validación puntual no es suficiente. Los cambios de esquema a veces son graduales: el proveedor introduce un campo nuevo en el 10 % de los registros durante días antes de extenderlo al 100 %. Si solo validas el esquema en binario —válido / inválido— ese drift pasa desapercibido.

Una capa de monitorización estadística del esquema resuelve esto. La idea es medir, para cada campo, la tasa de presencia, el tipo observado y la distribución de valores en ventanas de tiempo. Cuando esa distribución se desvía del histórico más allá de un umbral, se dispara una alerta.

Métricas mínimas a rastrear por campo:

Un campo que pasa de presence_rate: 0.98 a presence_rate: 0.61 en 24 horas es una señal de cambio en el proveedor, aunque la validación formal no haya fallado todavía. Detectarlo en ese momento —y no una semana después— es la diferencia entre un ajuste de media hora y una auditoría de datos retroactiva.

En entornos donde el volumen de señales es alto, como los pipelines que consumen fuentes del universo público de Internet a través de APIs como FeedScale, esta monitorización estadística es especialmente crítica: un drift en el esquema de una fuente de alta frecuencia puede contaminar miles de registros antes de que el error sea visible en las métricas de negocio.

Documentar el contrato como parte del pipeline, no como tarea pendiente

El schema registry no es solo una herramienta técnica. Es la documentación viva del contrato con el proveedor. Cada versión del esquema debe incluir:

Este registro convierte lo que suele ser conocimiento tribal —"ah, eso lo cambió el proveedor en febrero"— en un artefacto trazable que cualquier miembro del equipo puede consultar. Y cuando el proveedor vuelve a cambiar el esquema —porque lo hará— el equipo tiene el contexto necesario para actuar en minutos, no en días.


El esquema externo nunca será tu aliado estable. Pero una arquitectura que lo trata como variable —y no como constante— convierte cada cambio del proveedor en un evento gestionado, no en una crisis. Esa diferencia es la que separa un pipeline frágil de uno que aguanta en producción.


← Volver al blog