Data APIs: cómo gestionar el versionado para que los pipelines no mueran en silencio
Data APIs: cómo gestionar el versionado para que los pipelines no mueran en silencio
El pipeline llevaba semanas funcionando sin incidencias. Luego, un martes por la mañana, los datos dejaron de llegar. No había error explícito. El endpoint respondía 200. El JSON parecía correcto. El problema estaba en un campo que había cambiado de tipo: lo que antes era un string ahora era un array. La API había publicado la v2 sin deprecar la v1. El equipo tardó seis horas en diagnosticarlo.
Este escenario no es excepcional. En arquitecturas que consumen datos de APIs externas, el versionado mal gestionado es una de las causas más frecuentes de fallos silenciosos. No rompe el sistema de forma espectacular. Lo degrada, introduce errores de parsing, genera datos corruptos que viajan aguas abajo durante horas antes de que alguien los detecte.
La buena noticia: hay patrones claros para gestionar esto. La mala: requieren disciplina desde el día uno, no como parche cuando ya falla.
Por qué el versionado de APIs de datos es distinto al versionado de APIs de negocio
Una API de negocio entrega un recurso concreto: un pedido, un usuario, una transacción. Si cambia el esquema, el impacto es local y habitualmente visible de inmediato.
Una data API entrega señales en volumen: menciones, tendencias, textos, métricas de cobertura. Aquí el impacto de un cambio de esquema es diferente por dos razones. Primera, el volumen oculta el problema. Si de mil registros diarios, cincuenta empiezan a llegar sin un campo crítico, el pipeline no falla, solo produce análisis incompleto. Segunda, los consumidores downstream (modelos de ML, dashboards, sistemas de alerta) asumen implícitamente la consistencia del esquema. Cuando esa consistencia se rompe, el fallo puede aparecer a días de distancia y en un sistema completamente distinto al origen.
Por eso, la estrategia de versionado para data APIs no puede ser la misma que para APIs de recursos.
Los tres patrones de versionado que realmente se usan en producción
Versionado por URL (/v1/, /v2/) es el más extendido. Su ventaja es la visibilidad: el consumidor sabe exactamente qué versión está usando. Su desventaja es que exige mantener múltiples versiones activas en paralelo, y los proveedores no siempre respetan los plazos de deprecación prometidos. El equipo técnico debe tener un proceso formal para detectar cuándo la v1 deja de servir datos frescos, no solo cuándo devuelve error.
Versionado por cabecera (Accept: application/vnd.api+json;version=2) es más limpio desde el punto de vista de la URL, pero más frágil en la práctica. Depende de que la capa de cliente gestione correctamente las cabeceras, y en pipelines con múltiples capas de intermediación (proxies, gateways, caches), esa cabecera puede perderse o sobrescribirse sin que nadie lo note.
Versionado implícito por campo es el más peligroso. El proveedor añade campos nuevos sin incrementar versión, o cambia el tipo de uno existente argumentando "compatibilidad hacia atrás". Aquí la única defensa real es la validación de esquema en el punto de entrada del pipeline, antes de que el dato avance.
Ninguno de los tres es perfecto. Lo que funciona es combinarlos con observabilidad activa, no pasiva.
Qué significa validar el esquema en el punto de entrada
La validación de esquema en el ingreso no es opcional en data APIs de alta frecuencia. Significa rechazar o aislar registros que no cumplan el contrato esperado, antes de procesarlos.
En la práctica, un equipo con un pipeline maduro define un schema contract por cada versión de API que consume. Puede ser JSON Schema, Pydantic, Avro, o incluso una validación manual simple. Lo relevante es que esta validación ocurra en la capa de ingesta, no en la capa de análisis.
from pydantic import BaseModel, ValidationError
from typing import Optional, List
class MentionRecord(BaseModel):
id: str
source_url: str
published_at: str
sentiment_score: Optional[float] = None
tags: List[str] = []
def ingest(raw_record: dict) -> MentionRecord | None:
try:
return MentionRecord(**raw_record)
except ValidationError as e:
log_schema_violation(raw_record, e)
return None
Este patrón hace dos cosas. Primero, impide que un registro malformado envenene el análisis downstream. Segundo, genera un log de violaciones de esquema que, analizado en el tiempo, detecta cambios silenciosos del proveedor antes de que escalen.
Si en un día normal tienes cero violaciones y hoy tienes doscientas, algo cambió en el origen. Esa señal vale más que cualquier documentación de changelog.
Gestionar la deprecación: no confíes en los plazos del proveedor
Los proveedores de data APIs suelen anunciar deprecaciones con antelación. En la teoría, tienes tres meses para migrar. En la práctica, los plazos se incumplen en ambas direcciones: a veces la versión antigua deja de servir datos antes de lo previsto, otras veces sigue activa indefinidamente mientras la documentación dice lo contrario.
La estrategia defensiva es sencilla pero requiere automatización. Añade un monitor que consulte periódicamente las release notes o el changelog del proveedor. Si el proveedor expone una cabecera de deprecación (Deprecation, Sunset), léela en cada respuesta y alerta si aparece. No esperes a que el equipo recuerde revisarlo manualmente.
def check_deprecation_headers(response_headers: dict):
if "Sunset" in response_headers:
alert(f"API Sunset anunciado: {response_headers['Sunset']}")
if "Deprecation" in response_headers:
alert(f"Endpoint marcado como deprecated: {response_headers['Deprecation']}")
Este tipo de automatismo tiene coste de implementación bajo y evita que una deprecación planificada se convierta en una urgencia a las 2 AM.
Cuándo plantear una capa de abstracción interna
Si el equipo consume más de dos versiones distintas de la misma API, o si la API cambia con frecuencia alta, tiene sentido introducir una capa de abstracción interna: un adaptador que normaliza la salida de la API hacia un esquema interno estable.
El contrato interno no cambia aunque cambie la API externa. La migración de v1 a v2 del proveedor se gestiona en el adaptador, no en todos los consumidores internos.
[API v1 / v2] → [Adapter layer] → [Internal schema] → [Pipeline / Analytics]
El coste de esta abstracción es real: más código, más tests de contrato, más superficie de mantenimiento. Pero en pipelines de análisis de menciones o tendencias donde la estabilidad del esquema es crítica para la calidad del análisis, la inversión se amortiza rápido.
Plataformas como FeedScale que sirven datos derivados del universo público aplican versionado explícito precisamente para que los integradores puedan construir estas capas de abstracción con garantías. Pero incluso con buena documentación del proveedor, la responsabilidad de la estabilidad interna recae siempre en el equipo consumidor.
El versionado no es un problema de API, es un problema de equipo
El fallo del martes por la mañana no ocurrió porque la API cambiara. Ocurrió porque nadie había definido quién era responsable de detectar ese cambio antes de que llegara a producción.
Gestionar el versionado de data APIs requiere tres cosas: validación de esquema en el ingreso, monitorización activa de señales de deprecación, y un propietario interno de cada contrato de API. Sin las tres, el pipeline sobrevivirá hasta que no sobreviva, y el diagnóstico siempre será más caro que la prevención.