OpenAPI Diff
Una comparación OpenAPI contrasta dos versiones de una especificación de API —el contrato antiguo y el nuevo— e informa de lo que realmente cambió: endpoints eliminados, parámetros que pasaron a ser obligatorios, campos cuyo tipo cambió, valores de enumeración que desaparecieron. Carga o pega ambas especificaciones abajo y esta página clasifica cada cambio como incompatible o compatible, para que juzgues una actualización de un proveedor, o tu propia versión, antes de que llegue a producción. Ambos archivos se analizan en esta página, en tu dispositivo: no se sube nada, algo importante porque las especificaciones describen endpoints internos que quizá no quieres en el servidor de otro. ¿Nuevo en este vocabulario? El artículo complementario, los cambios incompatibles de API, explicados, define cada término usado aquí.
Última actualización:
Especificación antigua (el contrato que los clientes usan hoy)
Suelta un archivo en cualquier lugar de este panel, elige uno o pega el texto. El análisis es local; nada sale de este dispositivo.
Especificación nueva (el contrato candidato)
Suelta un archivo en cualquier lugar de este panel, elige uno o pega el texto. El análisis es local; nada sale de este dispositivo.
Resultado de la comparación
Resumen copiado al portapapeles.
Qué comprueba esta herramienta — y qué significa realmente «incompatible»
Un cambio es incompatible cuando un cliente escrito correctamente contra la especificación antigua puede fallar contra la nueva sin cambiar ni una línea de su propio código. Esa definición guía cada veredicto de esta página. Eliminar una ruta o una operación es incompatible porque las llamadas existentes no tienen adónde ir. Eliminar un estado de respuesta —sobre todo un 2xx— es incompatible porque el manejo de errores del cliente se escribió alrededor del conjunto antiguo. Añadir un parámetro obligatorio o una propiedad de petición obligatoria es incompatible porque la petición válida de ayer es rechazada de repente. Cambiar el tipo o el formato de un campo es incompatible porque los analizadores, validadores y SDK generados dependen del tipo declarado. Eliminar un valor de enumeración es incompatible porque un cliente puede seguir enviándolo, o guardar datos que ya no puede interpretar. Todo lo demás —un endpoint nuevo, un parámetro opcional, un campo de respuesta nuevo, un valor de enumeración nuevo, un código de estado nuevo— se informa como compatible: los clientes antiguos siguen funcionando, aunque aún no puedan usar la nueva capacidad.
La comparación es estructural, no textual. Ambos documentos se normalizan en el mismo modelo antes de comparar nada: cada ruta y operación, sus parámetros indexados por nombre y ubicación, su cuerpo de petición y cada respuesta reducidos a una firma de esquema: un resumen determinista de tipos, formatos, nombres de propiedades, listas de obligatorios y valores de enumeración, construido recursivamente y con las referencias locales $ref resueltas. Por eso reordenar claves, reformatear espacios o reescribir cada descripción produce una comparación vacía: nada de eso cambia el contrato. Y por eso un cambio enterrado a tres niveles dentro de un esquema referenciado también se encuentra: la firma expande la referencia en lugar de comparar su nombre.
Se aceptan dos formas de entrada porque el ecosistema publica ambas: primero se intenta JSON y, cuando eso falla, el texto se analiza como YAML, el formato que usan la mayoría de los documentos OpenAPI escritos a mano. Los documentos Swagger 2.0 también funcionan, incluidos sus parámetros in: body y los esquemas por respuesta. Deliberadamente no hay obtención remota ni subida: pega los documentos o suelta los archivos, igual que harías con una captura HAR, y la comparación se ejecuta cuando pulsas el botón —no con cada tecla—, de modo que dos especificaciones grandes pegadas siguen respondiendo con fluidez.
Usa el resultado como una puerta de publicación, no como decoración. En una revisión, la lista de incompatibles es el orden del día: cada entrada necesita una corrección, una subida de versión, una ventana de obsolescencia o una decisión escrita de que la ruptura es intencionada y está comunicada. La lista de compatibles es el borrador del registro de cambios. Exportar la comparación como JSON te permite archivar esa decisión junto a la versión, y el resumen copiable entra directamente en una solicitud de cambios: la misma disciplina que aplicarías a un cambio de contrato de webhook, donde una carga alterada en silencio rompe a todos los suscriptores a la vez.
Límites honestos, dichos con claridad. Esta herramienta compara el contrato declarado: no puede ver el comportamiento que la especificación no declara, como un campo que mantiene su tipo pero cambia su significado, una regla de negocio nueva, límites de velocidad más estrictos o un mensaje de error que los clientes analizaban (imprudentemente). Sigue las referencias locales y compara esquemas hasta una profundidad limitada, así que los esquemas patológicamente anidados o mutuamente recursivos se resumen en lugar de expandirse para siempre. Y una comparación con cero cambios incompatibles no es una promesa de que una actualización sea segura: es la evidencia de que el contrato documentado se mantuvo, que es exactamente la evidencia que vale la pena tener antes de desplegar.
La tabla de clasificación contra la que puntúa esta página
| Ruta u operación eliminada | Incompatible. Las llamadas a un endpoint que ya no existe fallan sin más; no hay forma compatible de que un cliente antiguo siga funcionando contra él. |
| Estado de respuesta eliminado | Incompatible. La lógica de reintentos, manejo de errores y supervisión del cliente se escribe contra el conjunto de estados declarado; perder un 2xx es la forma más grave. |
| Parámetro que pasó a ser obligatorio / campo obligatorio añadido | Incompatible. Las peticiones válidas bajo la especificación antigua son rechazadas por la nueva, así que cada cliente existente debe cambiar antes de poder llamar al endpoint. |
| Tipo o formato cambiado | Incompatible. Los analizadores, validadores y SDK generados se construyen desde el tipo declarado; de integer a string (o de int32 a int64) rompe los clientes estrictos aunque los valores parezcan parecidos. |
| Propiedad eliminada (petición o respuesta) | Incompatible. Una propiedad de petición que los clientes envían se ignora o se rechaza; una propiedad de respuesta que los clientes leen se vuelve nula o ausente en su código. |
| Valor de enumeración eliminado | Incompatible. Los clientes pueden seguir enviando el valor eliminado, o guardar datos que lo usan. Los valores añadidos son compatibles y se informan por separado. |
| Incorporaciones | Compatible. Las rutas, operaciones, parámetros opcionales, propiedades de petición opcionales, propiedades de respuesta, estados de respuesta y valores de enumeración nuevos nunca invalidan una interacción previamente válida. |
Preguntas frecuentes
¿Mis archivos de especificación se suben a algún sitio?
No. Ambos documentos se analizan y comparan en esta página, en tu dispositivo; compararlos no realiza ninguna petición de red y no se almacena nada. Es una regla deliberada: una especificación es un mapa de tu API —incluidos los endpoints internos y no documentados— y una herramienta que te pidiera subirla para compararla estaría recopilando exactamente el mapa que debes mantener privado.
¿Qué formatos se aceptan?
OpenAPI 3.x y Swagger 2.0, como JSON o YAML. El texto se intenta primero como JSON y se analiza como YAML cuando eso falla. Un documento debe llevar un objeto paths para ser reconocido como especificación; cualquier otra cosa se informa como «no es una especificación» en lugar de producir en silencio una comparación vacía.
¿Qué cuenta aquí como cambio incompatible?
Todo lo que puede hacer fallar a un cliente antiguo bien escrito: rutas, operaciones o estados de respuesta eliminados; parámetros o propiedades de petición que pasaron a ser obligatorios; cambios de tipo o formato; propiedades de petición o respuesta eliminadas; y valores de enumeración eliminados. Añadir cualquier cosa opcional es compatible. Los cambios de descripción, título y formato se ignoran por completo: no son cambios de contrato.
¿Cómo se tratan los esquemas referenciados?
Las referencias locales como #/components/schemas/Pet (o #/definitions/Pet en Swagger 2.0) se resuelven al construir las firmas, así que un cambio dentro de un esquema compartido se informa en cada operación que lo usa. La resolución tiene profundidad limitada y es segura ante ciclos, así que los esquemas recursivos no pueden bloquear la comparación.
¿Puedo archivar o compartir un resultado?
Sí. El botón de descarga exporta la comparación completa como JSON —los conteos del resumen más cada cambio con su severidad, tipo, ruta, método y detalle estructurado— y el botón de copiar produce un resumen en texto plano para una solicitud de cambios o una nota de versión. Ambos se generan localmente a partir de la comparación que acabas de ejecutar.