DEV Community

Cover image for ¿Cómo diseñar y desarrollar APIs con un enfoque Git-native?
Roobia
Roobia

Posted on • Originally published at apidog.com

¿Cómo diseñar y desarrollar APIs con un enfoque Git-native?

La mayoría de los equipos de API tratan el contrato como algo secundario: primero implementan, luego generan una especificación y finalmente descubren que ambas cosas se separan. El diseño de API nativo de Git invierte ese orden: el contrato vive como código fuente, se versiona en Git y cada cambio se revisa igual que la lógica de la aplicación.

Prueba Apidog hoy

Esta guía se centra en la práctica. Verá cómo diseñar contratos en ramas, revisarlos en pull requests y convertir una especificación confirmada en mocks, pruebas y documentación. El objetivo es simple: que su historial de Git sea también el historial de su API.

Si ya conoce el enfoque spec-first y quiere 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 cómo implementarlo en su equipo.

Qué significa “nativo de Git” para el trabajo con API

Un flujo nativo de Git significa que la definición de su API vive en el repositorio como un archivo de texto plano: .yaml, .json, .proto, SDL de GraphQL u otro formato comparable.

No está en una base de datos propietaria. No depende de una exportación manual. No queda bloqueada detrás de la interfaz de un proveedor.

El archivo en main es el contrato.

Diagrama de flujo de trabajo API nativo de Git

En este modelo, cualquier GUI, generador o documentación es una vista derivada del archivo versionado. Esto habilita capacidades que Git ya ofrece:

  • Historial con git log
  • Atribución de cambios con git blame
  • Reversión con git revert
  • Revisión mediante pull requests
  • Automatización con CI/CD

Una configuración nativa de Git tiene tres propiedades:

  1. La especificación está en el repositorio.
  2. Los cambios pasan por ramas, commits y merges.
  3. Los artefactos posteriores —mocks, clientes, pruebas y documentación— se generan desde el archivo confirmado.

Por qué diseñar y desarrollar APIs en Git

Usted ya confía en Git para su código. El contrato de API debe recibir el mismo tratamiento.

1. Historial trazable

Si alguien pregunta cuándo se agregó el parámetro cursor, Git responde:

git log -p api/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

Puede ver:

  • El commit que introdujo el cambio
  • El autor
  • La fecha
  • El mensaje
  • El diff exacto

No necesita capturas de pantalla ni registros externos.

2. Responsabilidad clara

Con git blame puede saber quién modificó cada línea:

git blame api/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

Si un campo tiene un nombre inconsistente o un tipo incorrecto, puede ir al commit y revisar la discusión de la PR.

3. Rollback rápido

Si un diseño incorrecto llega a main, puede revertirlo:

git revert <merge-commit>
Enter fullscreen mode Exit fullscreen mode

Después, regenere clientes, mocks y documentación desde la especificación revertida. No hay que limpiar manualmente una herramienta externa.

4. Revisión antes de implementar

Una pull request es el lugar natural para debatir el diseño de la API antes de escribir controladores.

Los revisores pueden comentar sobre:

  • Nombres de rutas
  • Campos requeridos
  • Tipos de datos
  • Códigos de estado
  • Compatibilidad con consumidores existentes
  • Paginación
  • Versionado

Una única fuente de verdad une todo el proceso. Frontend, backend, QA y documentación leen el mismo archivo. Esta es la base 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 recomendado es:

  1. Crear una rama
  2. Diseñar el contrato
  3. Confirmar el cambio
  4. Abrir una PR
  5. Revisar y fusionar
  6. Implementar contra el contrato aprobado

La implementación viene después del merge, no antes.

Suponga que quiere agregar un endpoint para listar facturas de un usuario. Cree una rama:

git checkout -b feat/api-invoices-list
Enter fullscreen mode Exit fullscreen mode

Edite el archivo OpenAPI:

# api/openapi.yaml
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
Enter fullscreen mode Exit fullscreen mode

Confirme el cambio:

git add api/openapi.yaml
git commit -m "Add GET /users/{userId}/invoices contract"
Enter fullscreen mode Exit fullscreen mode

Abra una pull request. El diff mostrará exactamente qué cambió: una ruta, una operación, parámetros y respuestas.

En la revisión, el equipo puede decidir:

  • Si status debe llamarse así
  • Si el enum necesita otros valores
  • Si 404 es correcto cuando el usuario no existe
  • Si debe existir paginación por cursor
  • Si la respuesta debe incluir metadatos

Una vez aprobada la PR, fusione a main. El backend implementa contra el contrato ya acordado. Este es el principio del desarrollo de API spec-first: el acuerdo precede al código.

Estrategia de ramas para contratos de API

Trate los cambios de contrato como cambios de código: una rama por unidad lógica.

Evite ramas que agregan veinte endpoints a la vez. Una PR pequeña se revisa mejor que una PR gigante.

Use prefijos claros:

Tipo de cambio Prefijo de rama Ejemplo Peso de 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, requiere aprobación
Corrección en la especificación fix/api- fix/api-status-enum-typo Ligero
Refactorización sin cambio semántico chore/api- chore/api-reorder-schemas Ligero

El prefijo comunica intención.

Una rama break/api- indica que los revisores deben comprobar consumidores, versionado y estrategia de desaprobación. Una rama chore/api- indica que no debería existir cambio de comportamiento.

Modelo de ramas recomendado

Para la mayoría de equipos de API, prefiera desarrollo basado en tronco.

Modelo Mejor para Implicación para API
Basado en tronco Entrega continua, equipos pequeños o medianos Cambios pequeños; menos conflictos
Gitflow Lanzamientos programados o regulados Ramas largas; merges más grandes y riesgosos

El desarrollo basado en tronco reduce conflictos de YAML porque las ramas viven poco tiempo y los diffs son pequeños.

Revisión de diseño de API en pull requests

Una PR de especificación no es solo una revisión de sintaxis. Es una revisión de diseño.

Use esta lista de verificación:

¿Rompe consumidores existentes?

Revise si el cambio:

  • Elimina campos
  • Cambia tipos
  • Renombra rutas
  • Cambia códigos de estado
  • Modifica enums existentes
  • Hace requerido un campo antes opcional

Ejemplo de cambio aditivo seguro:

parameters:
  - name: status
    in: query
    schema:
      type: string
-     enum: [draft, open, paid, void]
+     enum: [draft, open, paid, void, uncollectible]
Enter fullscreen mode Exit fullscreen mode

Agregar un valor puede ser aceptable si los consumidores toleran valores nuevos. Eliminar void, en cambio, sería disruptivo.

¿La nomenclatura es consistente?

Compare con el resto de la API:

  • ¿Las colecciones usan plural?
  • ¿Los IDs se llaman id, userId o user_id?
  • ¿Los errores usan siempre code y message?
  • ¿Los timestamps usan createdAt o created_at?

La API debe sentirse como un sistema coherente, no como endpoints escritos por equipos aislados.

¿El diff es legible?

Mantenga el YAML estable:

  • Ordene claves de forma consistente
  • Agregue rutas en ubicaciones predecibles
  • Evite reordenar archivos completos
  • Separe refactors de cambios semánticos

Un diff pequeño permite revisión real. Un archivo reordenado oculta el cambio importante.

Del diseño al desarrollo

Cuando el contrato entra en main, úselo como fuente para todo lo demás.

Flujo desde especificación hacia código, mocks, pruebas y documentación

Generar código

Herramientas como openapi-generator pueden producir stubs de servidor y clientes tipados.

Ejemplo:

openapi-generator-cli generate \
  -i api/openapi.yaml \
  -g typescript-fetch \
  -o generated/clients/typescript
Enter fullscreen mode Exit fullscreen mode

El backend implementa la lógica de negocio, pero las formas de request y response ya están definidas por el contrato.

Generar mocks

Un mock server puede leer la especificación y devolver respuestas de ejemplo. Esto permite que frontend avance antes de que el backend esté listo.

Flujo práctico:

  1. Se fusiona el contrato.
  2. Se inicia un mock desde openapi.yaml.
  3. Frontend consume el mock.
  4. Backend implementa la misma especificación.
  5. Las pruebas validan que ambos coincidan.

Ejecutar pruebas de contrato

Las pruebas de contrato validan que el servidor real cumple la especificación.

El flujo típico en CI:

  1. Levantar la aplicación.
  2. Enviar requests reales.
  3. Validar responses contra OpenAPI.
  4. Fallar el pipeline si hay divergencia.

La desviación entre especificación y código deja de ser un problema de producción y se convierte en un fallo de CI.

Generar documentación

La documentación de referencia debe renderizarse desde la especificación confirmada. Así, cuando cambia el contrato, cambia también la documentación.

Evite documentación escrita a mano para detalles como:

  • Parámetros
  • Schemas
  • Códigos de estado
  • Ejemplos de request/response

Esos datos deben venir del contrato.

Convenciones de equipo que escalan

Las convenciones evitan que el flujo nativo de Git se desordene cuando el equipo crece.

1. Decida la estructura de archivos

Para APIs pequeñas, un solo archivo puede ser suficiente:

api/openapi.yaml
Enter fullscreen mode Exit fullscreen mode

Para APIs medianas o grandes, divida por recursos:

api/
  openapi.yaml
  paths/
    users.yaml
    invoices.yaml
  schemas/
    user.yaml
    invoice.yaml
Enter fullscreen mode Exit fullscreen mode

Luego agrupe la especificación en CI o durante el build.

2. Versione deliberadamente

Actualice info.version cuando el contrato cambie.

Regla práctica:

  • Cambios aditivos: versión menor
  • Correcciones sin cambio de contrato: patch
  • Cambios disruptivos: versión mayor

Ejemplo:

info:
  title: Billing API
  version: 2.1.0
Enter fullscreen mode Exit fullscreen mode

Para cambios mayores, considere también una ruta nueva:

/v2/invoices
Enter fullscreen mode Exit fullscreen mode

3. Mantenga un CHANGELOG

Git es preciso, pero no siempre fácil de leer. Agregue un CHANGELOG.md junto a la especificación:

# Changelog

## 2.1.0

- Agregado `GET /users/{userId}/invoices`
- Agregado filtro opcional `status`
- Agregado schema `InvoiceList`
Enter fullscreen mode Exit fullscreen mode

Esto ayuda a consumidores internos y externos a entender qué cambió.

4. Proteja la especificación con CODEOWNERS

Use CODEOWNERS para requerir aprobación de responsables de API:

# .github/CODEOWNERS
/api/openapi.yaml @api-stewards
/api/paths/ @api-stewards
/api/schemas/ @api-stewards
Enter fullscreen mode Exit fullscreen mode

Así, cualquier cambio en el contrato pasa por revisión especializada.

5. Ejecute lint en CI

Use un linter para detectar problemas de estilo antes de la revisión humana.

Ejemplo con Spectral en GitHub Actions:

# .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
Enter fullscreen mode Exit fullscreen mode

Con linting y CODEOWNERS, cada cambio de contrato tiene dos barreras:

  • Verificación automática
  • Revisión humana

Errores comunes y cómo evitarlos

Error 1: la especificación y el código se separan

El contrato dice una cosa y el servidor responde otra.

Solución:

  • Genere stubs o tipos desde la especificación.
  • Ejecute pruebas de contrato en CI.
  • Falla el pipeline si la respuesta real no coincide con OpenAPI.

Error 2: PRs demasiado grandes

Una rama que agrega demasiados endpoints no se revisa bien.

Solución:

  • Una PR por endpoint o cambio lógico.
  • Separe refactors de cambios funcionales.
  • Mantenga diffs pequeños.

Error 3: clientes y documentación escritos a mano

Los artefactos manuales se desincronizan.

Solución:

  • Genere clientes desde openapi.yaml.
  • Genere documentación desde la especificación.
  • Regenere en cada merge o release.

Error 4: conflictos de merge en YAML

Las ramas largas y los archivos reordenados generan conflictos difíciles.

Solución:

  • Use ramas cortas.
  • Mantenga orden estable.
  • Divida la especificación por recursos.
  • Prefiera desarrollo basado en tronco.

Dónde encaja Apidog

Puede implementar este flujo con un editor de texto, Git y herramientas CLI. Pero muchos equipos quieren una interfaz visual para diseñar APIs sin dejar de usar Git como fuente de verdad.

Ahí encaja el Modo Spec-First de Apidog.

El Modo Spec-First mantiene el archivo OpenAPI en su repositorio Git y permite sincronización bidireccional. Puede editar el contrato en el diseñador visual de Apidog o directamente en su editor. En ambos casos, el archivo en Git sigue siendo canónico.

Esto permite combinar:

  • Diseño visual
  • Ramas
  • Pull requests
  • Historial de Git
  • Revisión de contrato
  • CI/CD
  • Generación de artefactos

Consulte la documentación del Modo Spec-First para detalles de configuración.

La herramienta no reemplaza la disciplina. El repositorio sigue siendo la única fuente de verdad; Apidog funciona como una superficie visual sobre ese contrato.

Preguntas frecuentes

¿El diseño de API nativo de Git es solo para OpenAPI?

No. El mismo enfoque funciona con cualquier contrato basado en texto:

  • OpenAPI
  • AsyncAPI
  • gRPC .proto
  • GraphQL SDL

Si puede hacer diff, branch, commit y review, puede usar un flujo nativo de Git.

¿Cómo manejo cambios disruptivos?

Hágalo visible y deliberado:

  1. Use una rama con prefijo break/api-.
  2. Aumente la versión mayor.
  3. Requiera aprobación mediante CODEOWNERS.
  4. Agregue una ruta nueva si es necesario, por ejemplo /v2.
  5. Mantenga la versión antigua durante un periodo de desaprobación cuando sea posible.

Ejemplo:

git checkout -b break/api-remove-legacy-id
Enter fullscreen mode Exit fullscreen mode

¿La especificación debe vivir en el mismo repositorio que el código?

Generalmente sí, si el mismo equipo mantiene API e implementación.

Ventajas:

  • Una PR puede cambiar contrato y código.
  • CI puede ejecutar pruebas de contrato en el mismo pipeline.
  • El equipo tiene una única fuente de verdad.

Use un repositorio separado si la API es compartida por muchos equipos y necesita versionado independiente.

¿Cómo evito que la especificación y el código diverjan?

Use tres capas:

  1. Generación de tipos, stubs o clientes desde la especificación.
  2. Pruebas de contrato en CI.
  3. Revisión de cambios de contrato mediante PR y CODEOWNERS.

Así, la divergencia se detecta antes de producción.

Conclusión

El diseño de API nativo de Git es una disciplina: trate el contrato como código fuente, evolúcionelo en ramas, revíselo en pull requests y genere los artefactos posteriores desde el archivo confirmado.

Empiece con pasos pequeños:

  1. Mueva la especificación al repositorio.
  2. Agregue lint en CI.
  3. Proteja el contrato con CODEOWNERS.
  4. Use PRs pequeñas para cambios de API.
  5. Genere clientes, mocks y documentación.
  6. Añada pruebas de contrato.

Con cada convención, el flujo se vuelve más sólido. Git deja de ser solo el historial del código y se convierte también en el historial completo de su API.

Si quiere una superficie visual que mantenga la especificación en Git, pruebe el Modo Spec-First de Apidog y evalúe cómo la sincronización bidireccional encaja en su flujo de trabajo.

Top comments (0)