La mayoría de los equipos de API tratan el contrato como algo secundario. Primero escriben el código, luego generan una especificación y luego ven cómo los dos se separan. El diseño de API nativo de Git invierte ese orden. Se trata el contrato de API como código fuente, se le aplica control de versiones en Git y se revisa cada cambio de la misma manera que se revisa la lógica de la aplicación.
Esta guía trata sobre la disciplina, no sobre una sola herramienta. Aprenderá a diseñar contratos en ramas, revisarlos en solicitudes de extracción (pull requests) y convertir una especificación confirmada en simulaciones (mocks), pruebas y documentación. El objetivo es un flujo de trabajo donde su historial de Git es su historial de API.
Si ya sabe cómo es la herramienta 'Spec-First' y desea un recorrido por el producto, lea el artículo complementario sobre el flujo de trabajo de API nativo de Git. Este artículo se centra en la práctica.
Qué significa “nativo de Git” para el trabajo con API
Nativo de Git significa que la definición de su API reside en su repositorio como un archivo de texto plano. No en una base de datos propietaria en la nube. No detrás de un inicio de sesión de proveedor. Un archivo .yaml o .json junto a su código, rastreado por el mismo control de versiones que su equipo ya utiliza.
Contraste esto con las herramientas bloqueadas en la nube. Muchas plataformas de diseño de API almacenan el contrato en su propio backend. Edita a través de una interfaz de usuario web, y la versión canónica reside en sus servidores. Su repositorio contiene, en el mejor de los casos, una exportación obsoleta. Cuando la base de datos del proveedor es la fuente de la verdad, su historial de Git no le dice nada sobre cómo evolucionó la API.

El modelo nativo de Git invierte esa relación. El archivo en main es el contrato. Todo lo demás, incluyendo cualquier interfaz gráfica de usuario (GUI), es una vista de ese archivo. Este simple cambio desbloquea el historial, la atribución de responsabilidades (blame), la reversión (rollback) y la revisión para la superficie de su API.
Una configuración nativa de Git tiene tres propiedades. La especificación es un archivo de texto en el repositorio. Los cambios fluyen a través de operaciones normales de Git como ramificar (branch), confirmar (commit) y fusionar (merge). Y cada artefacto posterior, desde simulaciones (mocks) hasta documentación, se deriva del archivo confirmado en lugar de una base de datos separada.
Por qué diseñar y desarrollar APIs en Git
Usted ya confía en Git con su activo más valioso: su código. Su contrato de API merece el mismo tratamiento.
El historial es la primera razón. Cuando alguien pregunta “¿cuándo agregamos el parámetro de paginación cursor?”, git log responde en segundos. La confirmación que lo introdujo lleva un mensaje, un autor y una fecha. Sin capturas de pantalla, sin arqueología de registros de cambios.
La atribución de responsabilidades (blame) es la segunda. Ejecute git blame en el archivo de especificación y verá exactamente quién cambió cada línea y por qué. Un nombre de campo confuso se remonta a la PR que lo agregó, con la discusión adjunta. La rendición de cuentas se vuelve automática.
La reversión (rollback) es la tercera. Un mal diseño se lanza. Con Git, usted git revert la fusión y el contrato vuelve a su estado anterior. La generación de código (codegen), las simulaciones (mocks) y la documentación posteriores se regeneran a partir del archivo revertido. No hay limpieza manual en un sistema separado.
La revisión es la cuarta, y es la que los equipos subutilizan. Una solicitud de extracción (pull request) es el lugar natural para debatir un diseño de API antes de que se haga realidad. Los revisores comentan sobre una línea + que agrega un campo requerido. La conversación permanece junto al cambio para siempre.
Una única fuente de verdad lo une todo. Cuando el contrato es un archivo en main, no hay ambigüedad sobre qué versión es la real. Frontend, backend, QA y documentación leen la misma línea de YAML. Esta es la promesa central de un flujo de trabajo de especificación de API basado en Git.
El ciclo de diseño de API nativo de Git
El ciclo tiene cinco pasos: diseñar el contrato, confirmar (commit), abrir una PR, revisar y fusionar (merge). La implementación sigue a la fusión, no al revés.
Comience escribiendo el contrato. Suponga que está agregando un endpoint para obtener las facturas de un usuario. Crea una rama y edita el archivo OpenAPI.
# openapi.yaml (fragmento añadido en la rama feat/invoices-list)
paths:
/users/{userId}/invoices:
get:
operationId: listUserInvoices
summary: Listar facturas de un usuario
parameters:
- name: userId
in: path
required: true
schema: { type: string, format: uuid }
- name: status
in: query
required: false
schema:
type: string
enum: [draft, open, paid, void]
responses:
"200":
description: Una página de facturas
content:
application/json:
schema:
$ref: "#/components/schemas/InvoiceList"
"404":
description: Usuario no encontrado
Confirme ese cambio con un mensaje claro: git commit -m "Add GET /users/{userId}/invoices contract". La confirmación es pequeña y enfocada. Describe una decisión de diseño.
Ahora abra una solicitud de extracción (pull request). El 'diff' muestra a los revisores exactamente lo nuevo: una ruta, una operación, dos parámetros, dos respuestas. Sus compañeros de equipo discuten el nombramiento, los valores del enumerador y si 404 es el código correcto para un usuario ausente. Podrían impulsar la paginación por cursor antes de que exista una sola línea de código del controlador.
Una vez aprobada la PR, fúsione. El contrato en main ahora incluye el endpoint de facturas. La implementación viene a continuación, y está limitada por la especificación que todos acordaron. Este orden es lo que la gente entiende por desarrollo de API 'spec-first': el acuerdo precede al código.
La recompensa es que los debates de diseño son económicos. Cambiar un campo YAML en revisión cuesta minutos. Cambiar un endpoint ya lanzado, implementado y documentado cuesta días.
Estrategia de ramificación para contratos de API
Trate los cambios de contrato como cualquier otro cambio: una rama por unidad lógica de trabajo. Una rama por endpoint o por modificación mantiene las PRs pequeñas y los 'diffs' legibles.
Nombre las ramas de modo que la intención sea obvia. Utilice un prefijo que indique la clase de cambio. Esto ayuda a los revisores y a la CI a enrutar el trabajo.
| Tipo de cambio | Prefijo de rama | Ejemplo | Peso de la revisión |
|---|---|---|---|
| Nuevo endpoint | feat/api- |
feat/api-invoices-list |
Estándar |
| Campo aditivo | feat/api- |
feat/api-invoice-currency |
Ligero |
| Cambio disruptivo | break/api- |
break/api-remove-legacy-id |
Pesado, necesita aprobación |
| Corrección de error en la especificación | fix/api- |
fix/api-status-enum-typo |
Ligero |
| Solo refactorización | chore/api- |
chore/api-reorder-schemas |
Ligero |
El prefijo tiene significado. Una rama break/api- indica a los revisores que reduzcan la velocidad y verifiquen cada consumidor. Una rama chore/api- señala que no hay cambio semántico, por lo que la revisión puede avanzar rápidamente.
También elige un modelo de ramificación. El desarrollo basado en troncos (trunk-based development) se adapta a la mayoría de los equipos de API. Las ramas de corta duración se fusionan en main diariamente, y la especificación se mantiene cerca de una única línea de verdad. Gitflow, con ramas develop y release de larga duración, se adapta a equipos que agrupan los cambios de API en lanzamientos programados.
| Modelo | Mejor para | Compromiso de API |
|---|---|---|
| Basado en tronco | Entrega continua, equipos pequeños | El contrato evoluciona en pequeños pasos; menos problemas de fusión |
| Gitflow | Lanzamientos programados, entregas reguladas | La especificación diverge en develop; fusiones más grandes y arriesgadas |
Para la mayoría del trabajo con API, prefiera el desarrollo basado en tronco. Los cambios pequeños y frecuentes en el contrato producen 'diffs' pequeños y frecuentes. Las ramas de larga duración permiten que la especificación se desvíe, y los conflictos de fusión de YAML se vuelven complicados rápidamente cuando dos ramas reestructuran el mismo archivo.
Revisión del diseño de API en solicitudes de extracción (pull requests)
Una PR de especificación es una revisión de diseño, no una verificación de sintaxis. Los revisores se fijan en la semántica, y unas pocas preguntas cubren la mayor parte del riesgo.
¿Esto rompe a los consumidores existentes? Eliminar un campo, renombrar una ruta o ajustar un tipo son todos cambios disruptivos. Un revisor comprueba si el cambio es aditivo o disruptivo, y los cambios disruptivos exigen un aumento de versión o una ruta de desaprobación.
¿La nomenclatura es consistente? Si cada endpoint de colección usa sustantivos plurales, una nueva ruta singular destacará. Si los errores devuelven un campo code en otro lugar, un nuevo endpoint también debería hacerlo. Los revisores aplican los patrones que la API ya estableció.
¿Es fácil de comparar con 'diff'? Mantenga el YAML estable para que los 'diffs' sigan siendo pequeños. Ordene las claves de manera consistente. Agregue nuevas rutas en un lugar predecible. Un revisor puede leer un 'diff' de cinco líneas en segundos, pero un archivo reordenado produce un 'diff' de cien líneas que oculta el cambio real.
Cambio disruptivo amigable para el revisor. Las líneas - señalan exactamente lo que desaparece.
# Diff que un revisor ve en la PR
parameters:
- name: status
in: query
schema:
type: string
- enum: [draft, open, paid, void]
+ enum: [draft, open, paid, void, uncollectible]
Ese 'diff' es aditivo al enumerador, por lo que es seguro. Compárelo con una línea - que elimina void por completo, lo que rompería cualquier cliente que envíe ese valor. El 'diff' hace visible la diferencia a primera vista.
Anime a los revisores a comentar en línea sobre la especificación, de la misma manera que comentan sobre el código. La discusión permanece adjunta a la línea y sobrevive en el historial fusionado.
Del diseño al desarrollo
Una vez que el contrato está en main, se convierte en la fuente para todo lo que viene después. Usted genera, no escribe a mano.

La generación de código (codegen) es lo primero. Herramientas como openapi-generator producen stubs de servidor y clientes tipados a partir del archivo confirmado. Sus controladores (handlers) rellenan la lógica de negocio, pero las formas de solicitud y respuesta coinciden con el contrato por construcción. La especificación y el código no pueden discrepar sobre el formato de transmisión.
Las simulaciones (mocks) vienen después. Un servidor de simulación lee la especificación y devuelve respuestas de ejemplo para cada endpoint. Los desarrolladores frontend construyen contra la simulación antes de que exista el backend. Comienzan en el momento en que el contrato se fusiona, no semanas después.
Siguen las pruebas. Las pruebas de contrato afirman que su servidor en ejecución coincide con la especificación. Envíe una solicitud, valide la respuesta contra el esquema y falle la compilación si divergen. Esta es la barrera de seguridad contra la desviación entre la especificación y el código.
La documentación también se genera. La documentación de referencia se renderiza directamente desde el archivo OpenAPI. Cuando el contrato cambia, la documentación cambia en la misma confirmación. No hay una actualización de documentación separada que olvidar.
El principio es consistente. Cada artefacto se deriva de un archivo confirmado. Regenere en cada fusión, y sus simulaciones (mocks), clientes, pruebas y documentación se mantendrán sincronizados con el contrato.
Convenciones de equipo que escalan
Las convenciones son lo que evita que un flujo de trabajo nativo de Git colapse a medida que el equipo crece. Decídalas temprano y anótelas.
Primero, elija entre un archivo de especificación y muchos. Un solo openapi.yaml es simple pero se vuelve inmanejable más allá de unas pocas docenas de endpoints. Dividirlo en varios archivos con referencias $ref mantiene cada archivo legible, a costa de un paso de agrupación. Un patrón común es un archivo por recurso, agrupado en una única especificación en tiempo de compilación.
Segundo, versione deliberadamente. Aumente la versión info.version de OpenAPI en cada cambio significativo y siga el versionado semántico. Los cambios aditivos aumentan la versión menor. Los cambios disruptivos aumentan la versión mayor y generalmente implican un nuevo prefijo de ruta como /v2/.
Tercero, mantenga un registro de cambios. Un archivo CHANGELOG.md junto a la especificación registra lo que cambió y por qué en términos humanos. El historial de Git es preciso pero verboso; el registro de cambios es el resumen legible que sus consumidores realmente escanean.
Cuarto, proteja la especificación con CODEOWNERS. Requiera a los encargados de la API que aprueben cualquier cambio en el archivo de contrato. Esto evita que los colaboradores bien intencionados publiquen diseños inconsistentes.
# .github/CODEOWNERS
/api/openapi.yaml @api-stewards
/api/paths/ @api-stewards
Quinto, use 'lint' en CI. Un linter detecta problemas de estilo y consistencia antes de la revisión. Ejecútelo en cada PR para que los humanos revisen el diseño, no el formato.
# .github/workflows/api-lint.yml
name: Lint de API
on:
pull_request:
paths: ["api/"]
jobs:
spectral:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Ejecutar Spectral
run: npx @stoplight/spectral-cli lint api/openapi.yaml --fail-severity warn
Con el 'linting' en CI más CODEOWNERS, cada cambio de contrato obtiene verificaciones automatizadas y un encargado humano. Esa combinación escala de tres ingenieros a trescientos.
Errores comunes y cómo evitarlos
El diseño de API nativo de Git tiene modos de fallo predecibles. Conocerlos le permite diseñar para evitarlos.
La desviación entre especificación y código es lo peor. El contrato dice una cosa; el servidor en ejecución hace otra. Evítelo con pruebas de contrato en CI que validen las respuestas en vivo contra la especificación confirmada. Si divergen, la compilación falla. La desviación se convierte en una tubería rota, no en una sorpresa en producción.
Las PRs gigantes son la siguiente trampa. Una sola rama que añade veinte endpoints produce un 'diff' no revisable. Los revisores lo hojean, aprueban y pasan por alto problemas. Divida el trabajo en un endpoint o un cambio por PR. Los 'diffs' pequeños obtienen una revisión real.
Los artefactos escritos a mano causan una inconsistencia silenciosa. Cuando alguien escribe un cliente a mano en lugar de generarlo, el cliente se desvía de la especificación. Genere clientes, stubs y documentación a partir del archivo confirmado cada vez. Trate los artefactos de API escritos a mano como una señal de alerta.
Los conflictos de fusión de YAML frustran a los equipos en ramas de larga duración. Dos ramas reestructuran el mismo archivo y Git no puede conciliarlas. Evite esto con ramas de corta duración, un orden de claves estable y un diseño de archivo dividido para que los cambios afecten a diferentes archivos. El desarrollo basado en tronco más PRs pequeñas elimina la mayoría de los conflictos antes de que comiencen.
El patrón en los cuatro casos es el mismo. Mantenga los cambios pequeños, derive los artefactos de la especificación y deje que CI aplique el contrato. La disciplina supera al heroísmo.
Dónde encaja Apidog
Puede ejecutar un flujo de trabajo nativo de Git con un editor de texto y una CLI. Muchos equipos quieren una GUI para el diseño sin renunciar a Git como fuente de la verdad. Esa es la brecha que llena el Modo Spec-First de Apidog.
El Modo Spec-First mantiene el archivo OpenAPI en su repositorio Git y tiene sincronización bidireccional. Edita el contrato en el diseñador visual de Apidog o en su editor, y ambos se mantienen consistentes con el archivo en su repositorio. El archivo en Git sigue siendo canónico, por lo que las ramas, las PRs y el historial funcionan exactamente como se describe aquí. Obtiene la GUI sin el bloqueo en la nube. Consulte la documentación del Modo Spec-First para obtener detalles de configuración.
El punto no es la herramienta. Es que puede tener una superficie de diseño visual y una disciplina nativa de Git al mismo tiempo. El repositorio sigue siendo la única fuente de la verdad, y Apidog se convierte en una vista de ello.
Preguntas Frecuentes
¿El diseño de API nativo de Git es solo para OpenAPI?
No. La disciplina se aplica a cualquier formato de contrato basado en texto. OpenAPI es el más común, pero el mismo flujo de trabajo funciona para AsyncAPI, archivos .proto de gRPC o GraphQL SDL. Siempre que el contrato sea un archivo de texto que pueda comparar (diff), ramificar y revisar, es nativo de Git.
¿Cómo manejo los cambios disruptivos en un flujo de trabajo nativo de Git?
Haga que los cambios disruptivos sean visibles y deliberados. Utilice un prefijo de rama break/api-, aumente la versión principal y requiera la aprobación del encargado a través de CODEOWNERS. Siempre que sea posible, agregue la nueva forma junto con la antigua y desapruebe la ruta antigua en un cronograma. El 'diff' de la PR y el aumento de versión juntos señalan la ruptura a cada consumidor.
¿Debería la especificación de la API vivir en el mismo repositorio que el código?
Generalmente sí, cuando un mismo equipo es dueño de ambos. Co-localizar la especificación y la implementación significa que una única PR puede cambiar el contrato y el controlador juntos, y las pruebas de contrato se ejecutan en una sola tubería. Coloque la especificación en un repositorio separado solo cuando muchos equipos consuman una API compartida y necesiten un versionado independiente.
¿Cómo evito que la especificación y el código se separen?
Agregue pruebas de contrato a CI. Envían solicitudes reales a su servidor en ejecución y validan cada respuesta contra la especificación confirmada. Una divergencia falla la compilación. Combinadas con la generación de stubs y clientes a partir de la especificación, las pruebas de contrato convierten la desviación en un fallo de la tubería en lugar de un error de producción.
Conclusión
El diseño de API nativo de Git es una disciplina, no un producto. Usted trata el contrato como código fuente, lo evoluciona en ramas, lo revisa en solicitudes de extracción (pull requests) y genera cada artefacto posterior a partir del archivo confirmado. El historial, la atribución de responsabilidades (blame), la reversión (rollback) y la revisión vienen de forma gratuita porque Git ya se los proporciona.
Empiece poco a poco. Mueva su especificación al repositorio, agregue un paso de 'lint', y requiera revisión en los cambios de contrato. Construya a partir de ahí con generación de código (codegen), simulaciones (mocks) y pruebas de contrato. El flujo de trabajo se acumula: cada convención facilita la siguiente, y su historial de Git se convierte en un registro completo de cómo creció su API.
Si desea una superficie de diseño visual que mantenga la especificación en Git, pruebe el Modo Spec-First en Apidog y vea cómo la sincronización bidireccional se ajusta al flujo de trabajo anterior.
