Un breaking change sin aviso quema la confianza de integración en un solo deploy. El API versioning existe para resolver ese problema: evolucionar la API con todo cliente existente corriendo en producción. La estrategia se decide en tres frentes: dónde vive la versión (URI, header o parámetro), cómo el CI detecta quiebres antes del merge y cómo jubilar una versión sin drama.

¿Qué merece una nueva versión?

Un cambio aditivo no rompe contrato alguno. Campo opcional nuevo en la respuesta, endpoint extra, parámetro con default: todo eso entra sin bump. Una versión nueva entra cuando el contrato cambia: renombrar campo, remover propiedad, cambiar tipo de string a integer, apretar validación. Versiona el contrato; el número de release es marketing.

Versión en la URL (/v1/, /v2/): ¿por qué sigue siendo el estándar REST?

El path versioning gana por pragmatismo. La versión aparece en el log de acceso, en el curl y en el navegador; el router dirige /v1/orders y /v2/orders a handlers distintos sin middleware; la CDN trata ambos como recursos separados en cache. El defecto es conceptual: /v2/ sugiere una API entera reversionada cuando el cambio afectó un solo recurso. Twilio lleva la idea al extremo con fechas en el camino (/2010-04-01/) y mantiene integraciones vivas hace más de una década.

Versionamiento por header Accept

En el modelo de header, el cliente envía Accept: application/vnd.minhaapi.v2+json y el servidor rutea por media type. Las URLs quedan limpias y la complejidad desaparece del camino del consumidor casual. El costo aparece en la operación: debuggear exige inspeccionar headers, la cache key de la CDN necesita listar el header (control de Vary en CloudFront o Fastly) y el soporte cruza headers para descubrir qué versión atendió cada request.

Contrato primero, código después

OpenAPI como fuente única de verdad cambia la dinámica del equipo. El CI corre oasdiff contra la spec anterior y falla el pipeline al detectar breaking change sin bump de versión. Los SDKs generados a partir de la spec quedan sincronizados con la implementación del servidor, y el mismo documento alimenta la documentación pública. El contrato versionado en git se vuelve historial auditable de decisiones.

¿Cómo desactivar una versión sin perder clientes?

  • Sunset header (RFC 8594) con la fecha de apagado en toda respuesta de la versión antigua
  • Aviso de deprecación dentro del payload durante la ventana de transición
  • Changelog público más email directo a los dueños de cada integración
  • Piso de 6 meses de ventana para B2B y 12 meses para contratos enterprise

El tráfico decide el apagado. Los logs de uso por cliente y por versión muestran quién todavía llama a /v1/; el sunset ocurre cuando la telemetría reporta cero llamadas. Sin esos logs, apagas en la fecha marcada y descubres el lunes que el cliente más grande seguía integrado.