OpenAPI y documentación de APIs Express.js | Nicolás Garzón
OpenAPI convierte el contrato HTTP en una especificación legible por personas y herramientas. Solo aporta valor cuando representa el comportamiento real de la aplicación.
Una especificación OpenAPI describe rutas, parámetros, bodies, responses, autenticación y schemas.
Texto
Copiar contrato OpenAPI
↓
documentación + validación + clientes + testsNo es únicamente una página Swagger. Es una fuente estructurada que puede utilizarse para detectar drift y coordinar equipos.
Sin contrato formal, los consumidores dependen de:
Conversaciones.
Ejemplos desactualizados.
Lectura del código.
Prueba y error.
Esto genera diferencias sobre campos opcionales, errores, auth, paginación y versiones.
YAML
Copiar openapi : 3.1.0
info :
title : Orders API
version : 1.0.0
paths :
/orders/{ orderId} :
get :
operationId : getOrder
parameters :
- name : orderId
in : path
required : true
schema :
type : string
format : uuid
responses :
'200' :
description : Order found
content :
application/json :
schema :
$ref : '#/components/schemas/Order'
'404' :
$ref : '#/components/responses/NotFound' Cada combinación método-path define una operación. operationId estable facilita SDKs y referencias.
Distingue path, query, header y cookie. Documenta required, defaults, límites y formatos.
Especifica media types y schemas. Un body JSON y un multipart no son intercambiables.
Documenta todos los resultados relevantes, no solo 200. Incluye status, headers y schema de error.
Describe bearer, cookie, OAuth2 o API key. Esto no implementa seguridad; solo declara el contrato.
Representan formatos públicos. No copies automáticamente modelos de base u ORM.
El contrato se diseña antes de implementar. Favorece revisión entre equipos y clientes, pero necesita disciplina para mantener runtime alineado.
Schemas y rutas generan OpenAPI. Reduce duplicación, pero puede documentar accidentalmente decisiones internas y no sustituye diseño.
Definir schemas de runtime reutilizados por validación y OpenAPI suele ser práctico. Aun así, verifica que transformación y responses coincidan.
OpenAPI 3.1 se alinea mejor con JSON Schema moderno. Herramientas antiguas pueden tener soporte parcial. La versión elegida debe seguir el ecosistema real de generación y validación.
TypeScript
Copiar const CreateOrderSchema = z. object ( {
customerId: z. string ( ) . uuid ( ) ,
items: z. array ( z. object ( {
productId: z. string ( ) . uuid ( ) ,
quantity: z. number ( ) . int ( ) . positive ( ) ,
} ) ) . min ( 1 ) ,
} ) ; Una integración puede convertir este schema a OpenAPI, pero debes añadir información que el runtime no conoce automáticamente: descripción, ejemplos, status, seguridad y semántica de negocio.
YAML
Copiar Problem :
type : object
required : [ code, status, message, requestId]
properties :
code :
type : string
status :
type : integer
message :
type : string
requestId :
type : string
details :
type : array
items :
type : objectEnumera códigos relevantes por operación cuando el cliente debe reaccionar.
Límite default y máximo.
Sorts permitidos.
Formato y opacidad del cursor.
Semántica de filtros repetidos.
Respuesta cuando el cursor es inválido.
Los ejemplos deben ser válidos y realistas. Un ejemplo que contiene campos inexistentes degrada la confianza más que no tenerlo.
Puedes validar ejemplos en CI contra los schemas.
El drift ocurre cuando el runtime y la spec divergen.
Validación de requests/responses en tests.
Contract tests.
Diff de OpenAPI en pull requests.
Generación desde schemas compartidos.
Auditoría de endpoints no documentados.
Herramientas de diff pueden señalar:
Campos eliminados.
Required añadido.
Tipo cambiado.
Status removido.
Path o método eliminado.
No toda alerta es realmente breaking y no todo cambio semántico puede detectarse. Revisión humana sigue siendo necesaria.
Un SDK generado reduce trabajo repetitivo, pero hereda defectos del contrato. Revisa:
Nombres de operationId.
Nullability.
Enums extensibles.
Errores.
Serialización de fechas.
Paginación.
No obligues a todos los consumidores a regenerar por cambios internos irrelevantes.
La documentación puede exponerse mediante Swagger UI, Redoc o un portal. Protege specs internas si revelan endpoints sensibles, aunque la seguridad no debe basarse en ocultamiento.
oneOf y discriminators con soporte desigual.
Campos nullable frente a opcionales.
Uploads y binary formats.
Streaming y SSE difíciles de expresar completamente.
Webhooks y callbacks.
Errores dependientes de estado.
Un test de integración puede validar la response real contra el schema. También prueba que cada operationId sea único y que referencias no estén rotas.
Documentar solo happy path.
Generar spec desde tipos TypeScript sin validación runtime.
Exponer entidades internas.
No versionar la spec junto al código.
Confiar en Swagger UI como prueba de corrección.
OpenAPI es contrato estructurado, no decoración.
Debe describir input, output, errores y seguridad.
Code-first no elimina diseño ni drift.
CI puede validar ejemplos, diffs y responses.
La spec pública debe representar el modelo del cliente, no la persistencia.
¿Qué diferencia existe entre schema TypeScript y OpenAPI?
¿Por qué documentar únicamente 200 es insuficiente?
¿Qué es drift y cómo se detecta?
¿Qué limitación tiene un detector automático de breaking changes?
Ver respuestas
TypeScript desaparece en runtime; OpenAPI describe el contrato HTTP serializado.
Porque clientes necesitan manejar validación, auth, conflictos y fallos.
Divergencia entre spec y runtime; se reduce con tests y generación coordinada.
No detecta todos los cambios semánticos y puede producir falsos positivos.
Integración con PostgreSQL lleva el contrato HTTP hacia persistencia, pooling e integridad.