¿Qué son los contratos de API? Definición, ejemplos y mejores prácticas

Todo fallo de integración tiene la misma historia de causa raíz. El equipo A construyó un endpoint. El equipo B lo consumió. En algún punto entre "el campo se llama userId" y "en realidad ahora es user_id", algo se rompió en producción, y dos equipos se pasaron una tarde en una sala de crisis discutiendo cuál de sus entendimientos de la API era el correcto.

La solución no es mejor comunicación. Es un mejor artefacto: un contrato de API. Una definición única, formal y acordada de lo que hace la API, contra la que ambas partes pueden construir, validar y exigirse mutuamente.

Esta guía cubre qué son los contratos de API, los formatos usados para distintos estilos de API, el desarrollo contract-first frente a code-first, cómo funcionan las pruebas de contrato de API, y las mejores prácticas que mantienen los contratos dignos de confianza a lo largo del tiempo.

¿Qué es un contrato de API?

Un contrato de API es la especificación formal y acordada de la interfaz de una API. Define, de forma precisa e inequívoca:

  • Operaciones -- Los endpoints, métodos, consultas o procedimientos que la API expone. Para una API REST, son las rutas y los verbos HTTP. Para gRPC, los servicios y las RPCs. Para una API basada en eventos, los canales y los tipos de mensaje.
  • Esquemas de petición y respuesta -- La forma exacta de los datos intercambiados: nombres de campo, tipos, obligatorios frente a opcionales, formatos y restricciones.
  • Semántica de errores -- Qué aspecto tiene un fallo. Qué códigos de error existen, qué significan y qué estructura siguen las respuestas de error.
  • Autenticación y autorización -- Cómo se identifican quienes llaman: claves de API, scopes de OAuth, claims de JWT, mTLS.
  • Reglas de versionado y estabilidad -- Qué partes de la interfaz son estables, cómo se introducen los cambios, cómo funciona la deprecación, y qué garantías (límites de tasa, SLAs) se compromete a ofrecer el proveedor.

La palabra clave es acordada. Un contrato no es solo una descripción de lo que el código hace hoy. Es un compromiso entre un proveedor y sus consumidores: "esta es la interfaz, y no la romperemos sin avisar". Ese compromiso es lo que hace posible el desarrollo independiente. El equipo de frontend puede construir contra el contrato mientras el backend todavía se está escribiendo. Un socio puede integrarse sin leer tu código fuente.

Si alguna vez has generado un SDK de cliente a partir de un archivo OpenAPI, has simulado un servicio a partir de su spec, o has rechazado un pull request porque rompía un esquema publicado, has usado un contrato de API como debe usarse: como la fuente de verdad de una interfaz.

Formatos de contrato de API: uno por estilo de API

No hay un formato de contrato universal, porque no hay un estilo de API universal. Cada familia de protocolos ha convergido en su propio estándar de especificación.

OpenAPI para APIs REST / HTTP

OpenAPI (antes Swagger) es el formato de contrato dominante para las APIs HTTP. Un documento OpenAPI describe rutas, operaciones, parámetros, cuerpos de petición, esquemas de respuesta, esquemas de autenticación y servidores -- todo en YAML o JSON.

paths:
  /orders/{orderId}:
    get:
      summary: Get an order by ID
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: The order
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
        "404":
          description: Order not found

El ecosistema en torno a OpenAPI es su verdadera fortaleza: visores de documentación interactiva, generadores de código de cliente y servidor, servidores de mock, validadores y linters consumen todos el mismo archivo.

Protocol Buffers para gRPC

Las APIs gRPC se definen en archivos .proto usando Protocol Buffers. El archivo proto es el contrato -- define servicios, métodos RPC y mensajes fuertemente tipados, y tanto el código de cliente como el de servidor se generan a partir de él.

service OrderService {
  rpc GetOrder(GetOrderRequest) returns (Order);
}

message GetOrderRequest {
  string order_id = 1;
}

Como la generación de código es obligatoria en gRPC, el drift de contrato entre la spec y la implementación es estructuralmente más difícil que en REST. Los campos numerados también codifican una política de evolución explícita: puedes añadir campos, pero renumerarlos o reutilizarlos rompe la compatibilidad.

GraphQL SDL para APIs GraphQL

GraphQL tiene el contrato integrado en el propio protocolo. El Schema Definition Language (SDL) describe cada tipo, consulta, mutación y suscripción que la API soporta, y el servidor lo impone: una petición que no coincide con el esquema se rechaza antes de que se ejecute cualquier resolver. La introspección significa que los consumidores siempre pueden obtener el contrato actual de la API en vivo.

AsyncAPI para APIs basadas en eventos

Las APIs asíncronas -- topics de Kafka, colas de RabbitMQ, subjects de NATS, WebSockets -- fueron durante años el lejano oeste de la documentación. AsyncAPI cambió eso adaptando el enfoque de OpenAPI a los sistemas basados en eventos. Un documento AsyncAPI describe canales, las operaciones sobre ellos (enviar/recibir), las cargas útiles de los mensajes y los bindings de broker. Para arquitecturas donde "¿quién publica qué, y quién lo consume?" es una pregunta diaria, un contrato AsyncAPI es la diferencia entre una respuesta y un proyecto de arqueología.

Esquemas de herramientas MCP para agentes de IA

El tipo de contrato más nuevo no describe en absoluto una interfaz servicio-a-servicio. El Model Context Protocol (MCP) permite a los servicios exponer herramientas a los agentes de IA, y cada herramienta viene con un nombre, una descripción y un JSON Schema para sus entradas. Esa lista de herramientas es un contrato de API genuino -- posiblemente uno de más riesgo, porque define lo que un agente autónomo tiene permitido hacer a tu sistema. Hemos escrito en profundidad sobre tratar las herramientas MCP como contratos de API y por qué merecen el mismo rigor de documentación que tus endpoints REST.

La conclusión: sea cual sea tu estilo de API, existe un formato de contrato legible por máquina para él. Los sistemas modernos suelen necesitar varios a la vez -- REST para la API pública, gRPC internamente, AsyncAPI para los eventos, MCP para los agentes -- que es exactamente la razón por la que los contratos se benefician de un único hogar en lugar de cinco repos dispersos.

Contract-First vs Code-First

Hay dos formas en las que un contrato llega a existir, y la elección moldea todo tu flujo de trabajo de API.

Contract-First (Design-First)

En el desarrollo contract-first, escribes la especificación antes de escribir cualquier implementación. El archivo OpenAPI o la definición proto se diseña, se revisa y se acuerda -- y luego tanto el proveedor como los consumidores construyen contra él, a menudo en paralelo.

Ventajas:

  • Desarrollo en paralelo. Los consumidores pueden generar clientes y construir contra mocks mientras el proveedor implementa. Nadie espera.
  • Revisión de diseño antes de la revisión de código. Es mucho más barato discutir sobre el nombre de un campo en un diff de YAML que refactorizar un endpoint ya entregado.
  • Coherencia. Diseñar los contratos como artefactos deliberados hace natural imponer convenciones de nombres, patrones de paginación y formatos de error en todas las APIs.
  • Foco en el consumidor. Diseñas la interfaz que los consumidores necesitan, no la interfaz que es más fácil de acoplar a tu modelo de datos existente.

Desventajas:

  • Más proceso por adelantado. Para un equipo de dos personas iterando sobre un endpoint interno, una fase de diseño formal puede ser sobrecoste.
  • Riesgo de drift si la implementación no se valida contra el contrato -- necesitas herramientas (middleware de validación, comprobaciones en CI) para mantenerlos honestos.

Code-First

En el desarrollo code-first, escribes la implementación y generas el contrato a partir de ella -- anotaciones, reflexión o introspección del framework producen el documento OpenAPI o el esquema GraphQL.

Ventajas:

  • Velocidad para equipos pequeños. Sin paso de diseño separado; el contrato siempre es derivable del código.
  • Sin drift por construcción. La spec generada coincide con la implementación, porque procede de la implementación.

Desventajas:

  • El contrato se convierte en un subproducto en lugar de un compromiso. Lo que sea que el código haga es lo que es la API -- incluidas las partes accidentales.
  • Los cambios incompatibles se cuelan con facilidad, porque nada obliga a revisar la interfaz como interfaz.
  • Las specs generadas suelen ser mediocres: descripciones que faltan, documentación de errores vaga, sin ejemplos.

¿Cuál deberías usar?

Una regla práctica pragmática: cuantos más consumidores tiene una API, y menos los controlas, más compensa contract-first. Las APIs públicas, las integraciones con socios y los contratos entre equipos separados merecen un tratamiento contract-first. Un endpoint interno consumido por un único frontend propiedad del mismo equipo puede ser code-first -- siempre que el contrato generado se siga publicando, versionando y comprobando ante cambios incompatibles.

Muchos equipos maduros llegan a un híbrido: code-first por velocidad, con barreras de CI a nivel de contrato (detección de cambios incompatibles, linting de esquemas) que les dan la mayor parte de la seguridad de contract-first.

Pruebas de contrato de API

Un contrato que nada verifica es un deseo. Las pruebas de contrato de API son la práctica de comprobar automáticamente que los proveedores y los consumidores se ajustan de verdad a la interfaz acordada. Dominan tres técnicas.

Pruebas de contrato dirigidas por el consumidor

En las pruebas de contrato dirigidas por el consumidor -- popularizadas por Pact -- cada consumidor registra las interacciones específicas de las que depende: "cuando hago GET /orders/123, espero un 200 con un cuerpo que contenga id, status y total". Esas expectativas registradas forman un contrato que luego se reproduce contra el proveedor en su pipeline de CI.

La fuerza de este enfoque es la precisión. El proveedor aprende exactamente qué campos usa de verdad cada consumidor. ¿Quieres eliminar un campo? Las pruebas de contrato te dicen de inmediato si algún consumidor se va a romper -- antes de desplegar, no después.

Validación de esquemas en CI

La técnica más simple y amplia: validar que la implementación coincide con la spec publicada.

  • Lanza peticiones contra el servicio y valida las respuestas contra los esquemas OpenAPI.
  • Usa middleware de validación que rechace cualquier respuesta que no se ajuste al contrato (genial en staging).
  • Haz lint de la propia spec para comprobar su completitud y estilo (Spectral y herramientas similares).

Esto captura el modo de fallo más común -- la spec dice una cosa, el código hace otra -- de forma barata y continua.

Detección de cambios incompatibles

Por último, compara el propio contrato. Herramientas como oasdiff (OpenAPI), Buf (protobuf) y GraphQL Inspector comparan la nueva versión de una spec con la anterior y clasifican cada cambio: aditivo (seguro) o incompatible (campo eliminado, tipo cambiado, nuevo parámetro obligatorio). Conecta esto a tu CI y un cambio incompatible se convierte en un build fallido que requiere una aprobación explícita y deliberada -- en lugar de una sorpresa silenciosa para tus consumidores.

Si solo haces una cosa de esta sección, haz esta. La detección de cambios incompatibles es barata de configurar y captura los fallos que más duelen.

Por qué los contratos de API pertenecen a tu documentación de arquitectura

Aquí está la parte que la mayoría de los equipos pasa por alto. Puedes tener preciosos archivos OpenAPI, suites Pact rigurosas y barreras de cambios incompatibles en CI -- y aun así ser incapaz de responder a la pregunta que importa cuando algo necesita cambiar: "¿quién depende de este contrato?".

Un archivo de contrato en un repositorio describe una interfaz, pero no dice nada sobre su contexto. ¿Qué servicio lo implementa? ¿Qué servicios, frontends y socios lo consumen? Si deprecamos este endpoint, ¿qué se rompe en realidad? Ese conocimiento suele vivir en las cabezas de las personas, lo que significa que se degrada cada vez que alguien cambia de equipo.

Aquí es donde la documentación de arquitectura y los contratos de API se necesitan mutuamente:

  • Un contrato sin contexto arquitectónico queda obsoleto de forma invisible. Nadie se da cuenta del openapi.yaml huérfano que describe un servicio reescrito el año pasado, porque nada lo conecta con el sistema que describe.
  • Un diagrama de arquitectura sin contratos es impreciso. Una flecha etiquetada como "REST/JSON" entre dos cajas te dice que existe una relación, pero no qué fluye por ella. El contrato es lo que le da significado a la flecha.

El modelo C4 proporciona la estructura natural para esta conexión: los contratos se adjuntan a los contenedores y componentes que los implementan y consumen (consulta nuestra entrada del glosario del modelo C4 para un repaso rápido de esos términos). El contenedor de API Gateway lleva su contrato OpenAPI. El microservicio interno lleva su archivo proto. Los servicios centrados en Kafka llevan el documento AsyncAPI que define sus canales.

Así es exactamente como funciona la funcionalidad de Contratos de API de Archyl: importas contratos OpenAPI, gRPC, GraphQL, AsyncAPI o MCP -- sincronizados desde git o pegados directamente -- y los enlazas con los elementos C4 de tu modelo de arquitectura. Los enlaces son bidireccionales: desde un contrato ves qué elementos lo implementan y consumen, y desde cualquier elemento del diagrama puedes abrir las specs reales que describen sus interfaces. Cuando un contrato cambia, puedes ver de un vistazo qué partes de la arquitectura están en el radio de impacto, en lugar de reconstruir el panorama de dependencias a partir del conocimiento tribal. Cubrimos la funcionalidad en detalle en Contratos de API: tus especificaciones de API, enlazadas a tu arquitectura.

El principio se mantiene al margen de las herramientas: un contrato es más valioso cuando vive junto a los elementos arquitectónicos que vincula, no en una carpeta que nadie abre.

Mejores prácticas de contratos de API: una checklist

Un contrato es un compromiso de larga vida, así que trátalo como tal:

  • Establece una única fuente de verdad. Una ubicación canónica por contrato. Si la spec existe en tres lugares, existe en cero lugares. Ya sea un repo de git o una plataforma de arquitectura como Archyl, todo el mundo debe saber dónde vive la versión autorizada.
  • Versiona explícitamente. Dale a cada contrato una versión, y define qué significa un cambio de versión. El versionado semántico funciona bien: los cambios aditivos suben la versión menor, los cambios incompatibles suben la mayor.
  • Nunca rompas sin una versión mayor. Eliminar un campo, cambiar un tipo, añadir un parámetro obligatorio, endurecer la validación -- todo incompatible. Requieren una nueva versión mayor o un nuevo endpoint, más una ruta de migración.
  • Escribe una política de deprecación y respétala. Marca las operaciones deprecadas en la spec, comunica una fecha de retirada, da a los consumidores una ventana realista (meses, no días), y monitoriza el uso antes de eliminar.
  • Revisa los cambios de contrato como los cambios de código. Un diff de esquema merece al menos tanto escrutinio como un diff de implementación -- tiene más consumidores.
  • Automatiza la imposición. Validación de esquemas y detección de cambios incompatibles en CI. Los humanos acuerdan el contrato; las máquinas lo imponen.
  • Documenta los errores y la autenticación, no solo el camino feliz. Los 400 y los 401 son donde los consumidores pasan su tiempo de depuración. Especifícalos.
  • Enlaza los contratos a tu arquitectura. Cada contrato debería ser rastreable hasta los componentes que lo implementan y los que lo consumen, para que el análisis de impacto sea una consulta, no una investigación.

Preguntas frecuentes

¿Cuál es la diferencia entre un contrato de API y la documentación de API?

La documentación de API está escrita para humanos: guías, tutoriales, ejemplos, explicaciones de conceptos. Un contrato de API es una especificación formal y legible por máquina que consumen tanto humanos como herramientas -- puede generar código, validar peticiones, dirigir mocks y hacer fallar builds de CI. La buena documentación a menudo se genera a partir del contrato, pero el contrato es el artefacto vinculante: la documentación describe la API, el contrato la define.

¿Qué es el desarrollo contract-first?

El desarrollo contract-first (o design-first) significa escribir y acordar la especificación de la API -- el documento OpenAPI, el archivo proto o el esquema GraphQL -- antes de implementarla. Los consumidores y proveedores construyen luego en paralelo contra la misma interfaz acordada. Adelanta la discusión de diseño, permite el trabajo en paralelo y convierte el contrato en un compromiso deliberado en lugar de un subproducto del código.

¿Qué son las pruebas de contrato de API?

Las pruebas de contrato de API verifican automáticamente que los proveedores y los consumidores se ajustan a la interfaz acordada. Incluyen pruebas de contrato dirigidas por el consumidor (estilo Pact, donde las expectativas del consumidor se reproducen contra el proveedor), validación de esquemas en CI (comprobar que la implementación coincide con la spec) y detección de cambios incompatibles (comparar versiones de la spec para señalar cambios incompatibles antes del lanzamiento).

¿Necesitan también contratos las APIs internas?

Sí -- posiblemente más, porque las APIs internas cambian más rápido y están protegidas por menos ceremonia. El contrato puede ser más ligero (la generación code-first está bien), pero igual debería publicarse, versionarse y comprobarse ante cambios incompatibles. La mayoría de los incidentes de producción causados por cambios de API son causados por cambios de API internas.


¿Listo para darle a tus contratos de API un hogar dentro de tu arquitectura? Explora la funcionalidad de Contratos de API de Archyl -- contratos OpenAPI, gRPC, GraphQL, AsyncAPI y MCP, enlazados a tu modelo C4. O sigue leyendo: Contratos de API: tus especificaciones de API, enlazadas a tu arquitectura | Herramientas MCP como contratos de API | ¿Qué es el modelo C4? Guía completa.