¿Qué es OpenAPI?
OpenAPI es una descripción legible por máquinas de una API HTTP. Escrito en YAML o JSON, un único documento enumera cada endpoint, sus parámetros, los cuerpos de las solicitudes (request bodies), las respuestas y la autenticación. Debido a que está estructurado, diversas herramientas pueden consumirlo: interfaces de documentación, clientes tipados, server stubs, mocks y validadores.
Swagger era el nombre original; ahora se refiere al conjunto de herramientas, especialmente a Swagger UI. La especificación en sí es OpenAPI, y se ha convertido en el estándar de facto para describir REST APIs. Si alguna vez has utilizado una referencia de API interactiva con un botón de “Try it out”, has utilizado OpenAPI.
La estructura de un documento
Un documento de OpenAPI tiene algunas secciones de nivel superior.
# openapi.yaml
openapi: 3.1.0
info:
title: Posts API
version: 1.0.0
servers:
- url: https://api.example.com/v1
paths:
/posts:
get:
summary: List posts
responses:
"200":
description: A list of posts
- openapi declara la versión de la especificación.
- info contiene el título, la versión y la descripción.
- servers enumera las URLs base.
- paths describe cada endpoint y sus operaciones.
- components contiene piezas reutilizables.
Rutas y operaciones
Cada ruta se mapea a uno o más métodos HTTP, y cada operación describe sus entradas y salidas.
# paths.yaml
paths:
/posts/{id}:
get:
summary: Get a post
parameters:
- name: id
in: path
required: true
schema: { type: string }
responses:
"200":
description: The post
content:
application/json:
schema:
$ref: "#/components/schemas/Post"
"404":
description: Not found
Los parámetros pueden estar en el path, query, header o cookie. Los cuerpos de las solicitudes se declaran con un tipo de contenido y un esquema, y cada respuesta debe enumerar sus códigos de estado y estructuras. Unos buenos resúmenes y descripciones convierten la especificación en documentación útil por sí misma.
Componentes y referencias
La reutilización es lo que permite que una especificación sea mantenible. Define las estructuras una sola vez y haz referencia a ellas con $ref.
# components.yaml
components:
schemas:
Post:
type: object
required: [id, title]
properties:
id: { type: string }
title: { type: string }
publishedAt: { type: string, format: date-time }
parameters:
Limit:
name: limit
in: query
schema: { type: integer, minimum: 1, maximum: 100 }
responses:
NotFound:
description: Resource not found
Cualquier cambio en el esquema de Post actualiza cada operación que lo referencia, lo que evita la desincronización que suele afectar a las definiciones duplicadas.
Seguridad
La autenticación se declara una sola vez y se aplica por operación.
# security.yaml
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
security:
- bearerAuth: []
De este modo, las herramientas pueden enviar las credenciales correctas en la UI de la documentación, y los clientes generados pueden aceptar un parámetro de token.
Documentación y generación de código
La especificación impulsa el tooling:
- Swagger UI renderiza una referencia interactiva donde los usuarios pueden probar las peticiones.
- Redoc renderiza una página de documentación limpia de tres paneles.
- openapi-generator produce clientes y stubs de servidor en muchos lenguajes.
- openapi-typescript genera tipos de TypeScript a partir de la especificación.
- Spectral aplica linting a la especificación para asegurar la consistencia y el estilo.
- Mock servers sirven respuestas de ejemplo para que el trabajo de front-end pueda comenzar antes de que el backend esté listo.
# docs.sh
npx @redocly/cli preview-docs openapi.yaml
npx openapi-typescript openapi.yaml -o src/api-types.ts
Debido a que todo deriva de un único archivo, la documentación, los clientes y los tipos se mantienen consistentes.
Spec-first frente a code-first
Existen dos flujos de trabajo:
- Spec-first: diseñar el contrato antes de la implementación. Es ideal para API públicas, múltiples consumidores y para trabajar el front-end y el back-end en paralelo. La especificación es la fuente de verdad.
- Code-first: anotar rutas y tipos, y luego generar la especificación. Mantiene la especificación cercana a la implementación y evita la duplicación en frameworks tipados.
Ambos funcionan. El error común en cualquiera de los dos casos es mantener la documentación a mano en un lugar separado, donde queda obsoleta silenciosamente.
Validación y pruebas de contrato
Un documento OpenAPI puede aplicarse estrictamente, no solo leerse.
- Validación de solicitudes: el middleware rechaza las solicitudes que no coinciden con la especificación, permitiendo que los handlers confíen en sus entradas.
- Validación de respuestas: las pruebas aseguran que las respuestas coincidan con sus esquemas declarados.
- Pruebas de contrato: tanto los clientes como los servidores verifican contra la misma especificación, detectando cambios disruptivos (breaking changes) a tiempo.
Aquí es donde la especificación demuestra su valor: se convierte en un contrato ejecutable en lugar de una simple decoración.
Mejores prácticas
- Mantén una especificación por API y trátala como la fuente de verdad.
- Reutiliza esquemas, parámetros y respuestas con
$ref. - Escribe resúmenes y descripciones claras; estos se convertirán en la documentación.
- Documenta cada código de estado que una operación pueda devolver.
- Valida las solicitudes y respuestas basándote en la especificación.
- Genera clientes, tipos y documentación en lugar de escribirlos a mano.
- Aplica linting a la especificación y revisa los cambios en los pull requests.
Errores comunes
- Mantener la documentación manualmente y por separado de la especificación.
- Duplicar esquemas inline hasta que dejan de coincidir.
- Omitir las respuestas de error, impidiendo que los clientes gestionen los fallos.
- Usar nombres y descripciones ambiguas que no ayudan a los consumidores.
- Permitir que la especificación se desvíe de la implementación.
- Omitir la validación y perder el beneficio principal del contrato.
Próximos pasos
OpenAPI convierte una API en un contrato que tanto las herramientas como las personas pueden utilizar. Constrúyela sobre un diseño REST sólido, evoluciona cuidadosamente mediante el versionado de API y alinéala con la guía de HTTP. Después, describe un endpoint que ya tengas y genera un cliente a partir de él.