Versionado de API y Compatibilidad hacia Atrás
Diseña estrategias de versionado de API que evolucionen de manera gradual sin romper a los consumidores existentes.
Disparadores de Activación
Actívalo en: "versionado de API", "compatibilidad hacia atrás", "desaprobación", "cambio disruptivo", "migración de API", "v1 v2", "cabecera sunset", "evolución de API", "cambio no disruptivo"
NO para: Evolución de esquemas de datos → schema-evolution-manager | Enrutamiento de versiones en gateway → api-gateway-reverse-proxy-expert | Desaprobación en GraphQL → graphql-server-architect
Inicio Rápido
- Clasifica el cambio — aditivo (seguro), modificación (posiblemente disruptivo), eliminación (disruptivo)
- Elige la estrategia — ruta URL (
/v2/), cabecera (API-Version), o negociación de contenido - Implementa cabeceras Sunset — RFC 8594 informa a los consumidores cuándo mueren las versiones antiguas
- Ejecuta versiones en paralelo — mínimo 6 meses de superposición para versiones mayores
- Monitoriza la adopción — rastrea el tráfico por versión para saber cuándo retirar
Capacidades Principales
| Dominio | Tecnologías |
|---|---|
| Versionado por URL | Enrutamiento basado en ruta /api/v1/, /api/v2/ |
| Versionado por Cabecera | API-Version: 2024-01-15, Accept-Version |
| Negociación de Contenido | Accept: application/vnd.myapi.v2+json |
| Desaprobación | Cabecera Sunset (RFC 8594), Cabecera Deprecation |
| Herramientas | Overlays OpenAPI 3.1, Optic, Bump.sh |
Patrones de Arquitectura
Árbol de Decisión de Estrategia de Versionado
¿Es solo aditivo? (nuevos campos, nuevos endpoints)
├─ SÍ → No se necesita salto de versión (compatible hacia atrás)
└─ NO → ¿Es un cambio de nombre/tipo de campo?
├─ SÍ → ¿Puedes mantener los campos antiguos y nuevos?
│ ├─ SÍ → Añade nuevo, desaprueba antiguo (versión menor)
│ └─ NO → Salto de versión mayor (v1 → v2)
└─ NO → ¿Es una eliminación?
└─ SÍ → Salto de versión mayor con período sunset
Despliegue de Versiones en Paralelo
// Enrutador Express con enrutamiento basado en versión
import { Router } from 'express';
const v1Router = Router();
const v2Router = Router();
// v1: devuelve { name: string }
v1Router.get('/users/:id', async (req, res) => {
const user = await getUser(req.params.id);
res.json({ name: user.fullName }); // forma heredada
});
// v2: devuelve { firstName, lastName, displayName }
v2Router.get('/users/:id', async (req, res) => {
const user = await getUser(req.params.id);
res.json({
firstName: user.firstName,
lastName: user.lastName,
displayName: user.fullName,
});
});
app.use('/api/v1', v1Router);
app.use('/api/v2', v2Router);
// Middleware de cabecera Sunset para v1
v1Router.use((req, res, next) => {
res.set('Sunset', 'Sat, 01 Nov 2026 00:00:00 GMT');
res.set('Deprecation', 'true');
res.set('Link', '</api/v2>; rel="successor-version"');
next();
});
Versionado Basado en Fecha (Modelo Stripe)
API-Version: 2026-03-15
Los cambios están vinculados a fechas, no a enteros:
2026-01-01 → línea base
2026-03-15 → renombrado `name` → `display_name`
2026-06-01 → eliminado `legacy_field`
El servidor asigna las solicitudes sin versión a la versión predeterminada de la cuenta.
Cada versión es una capa de transformación sobre el modelo interno canónico.
Antipatrones
- Versionar demasiado pronto — la mayoría de los cambios son aditivos y no requieren un salto de versión; añade campos libremente
- Sin cronograma sunset — desaprobar sin una fecha concreta de desactivación significa que las versiones viven para siempre
- Copiar controladores completos — usa una capa de transformación/adaptador, no lógica de negocio duplicada por versión
- Ignorar campos desconocidos — las API deben ser lectoras tolerantes; ignora campos desconocidos en la entrada (Ley de Postel)
- Cambios disruptivos en versiones menores — si los consumidores dependían de ello, eliminarlo es disruptivo independientemente de tu intención
Lista de Verificación de Calidad
- Los cambios aditivos (nuevos campos, nuevos endpoints) se envían sin salto de versión
- Los cambios disruptivos requieren una versión mayor con un período sunset de 6+ meses
- Cabecera Sunset (RFC 8594) establecida en versiones desaprobadas
- Cabecera Link que apunta a los consumidores hacia la versión sucesora
- Tráfico por versión monitorizado para rastrear el progreso de la migración
- Especificación OpenAPI publicada por versión con herramientas de diff (Optic/Bump.sh)
- Plan de notificación al consumidor: changelog, correo electrónico, advertencia en el panel
- Enrutamiento de versión manejado a nivel de gateway, no en el código de la aplicación
- Pruebas de integración que validan la compatibilidad hacia atrás (pruebas de contrato)