Definición
OpenAPI 3.x representa una evolución importante desde Swagger 2.0, incorporando patrones modernos de APIs en la especificación. Lanzado en 2017, OpenAPI 3.0 introdujo soporte para callbacks (webhooks), múltiples ejemplos de request/response, modelos de autenticación mejorados y una composición de schemas más limpia. OpenAPI 3.1 (2021) fue más allá al lograr compatibilidad completa con JSON Schema Draft 2020-12, facilitando la reutilización de schemas entre diferentes herramientas y especificaciones.
La serie 3.x cambió fundamentalmente cómo se describen las APIs complejas. Ahora puedes modelar suscripciones a webhooks, definir múltiples servidores para diferentes entornos, usar discriminadores para respuestas polimórficas y aprovechar todo el poder de JSON Schema, incluyendo condicionales, dependencias y reglas de validación avanzadas.
A diferencia de Swagger 2.0, que estaba estrechamente acoplado al ecosistema de herramientas Swagger, OpenAPI 3.x está diseñado para ser agnóstico de herramientas. Esto ha llevado a una explosión de herramientas compatibles para documentación, generación de código, testing y API gateways de varios proveedores y proyectos de código abierto.
Ejemplo
Definición de Webhook: Stripe usa OpenAPI 3.x para documentar sus callbacks de webhooks. Cuando te suscribes a eventos de pago, Stripe define el schema exacto de las cargas útiles de webhooks usando la característica de callbacks - algo imposible en Swagger 2.0.
Schemas Polimórficos: La API de GitHub usa discriminadores para modelar diferentes tipos de eventos (PushEvent, IssueEvent, PullRequestEvent) que comparten una estructura base pero tienen campos específicos por tipo. La característica de discriminador de OpenAPI 3.x hace esto claro tanto para humanos como para generadores de código.
Múltiples Ejemplos: Twilio documenta varios escenarios de request usando la característica de múltiples ejemplos de OpenAPI 3.x. Para enviar un SMS, muestran ejemplos con diferentes parámetros - texto simple, mensajes multimedia, envío programado - todo dentro de la definición de un único endpoint.
Servidores Específicos por Entorno: Los servicios de AWS definen múltiples URLs de servidor en sus specs de OpenAPI - producción, staging, endpoints regionales - permitiendo a las herramientas cambiar automáticamente entre entornos sin cambios manuales de URL.
Composición oneOf/anyOf: Las APIs de pasarelas de pago usan oneOf para modelar diferentes métodos de pago (tarjeta de crédito, transferencia bancaria, wallet digital) donde cada uno tiene campos obligatorios únicos. La composición de schemas de OpenAPI 3.x maneja esto elegantemente.
Analogía
El Manual de Instrucciones Mejorado: Si Swagger 2.0 era como un manual de instrucciones básico con pasos lineales, OpenAPI 3.x es la versión premium con diagramas desplegables, guías de múltiples escenarios y códigos QR vinculados a tutoriales en vídeo. No solo te dice cómo usar el producto - modela interacciones complejas como servicios de suscripción (webhooks) y opciones de personalización (schemas polimórficos).
El GPS Multi-Entorno: Swagger 2.0 era como un GPS con un mapa. OpenAPI 3.x es como tener múltiples capas de mapa (satélite, tráfico, terreno) y ubicaciones guardadas para casa/trabajo/vacaciones. La característica de múltiples servidores es como tener destinos preestablecidos para diferentes contextos - todo en un sistema.
El Libro de Elige Tu Propia Aventura: La composición de schemas de OpenAPI 3.x (oneOf, anyOf, allOf) es como una historia de elige tu propia aventura. Dependiendo de tus elecciones (campo discriminador), diferentes caminos (schemas) se vuelven disponibles. Swagger 2.0 era una novela lineal - una historia, un camino.
Ejemplo de Código
openapi: 3.1.0
info:
title: Payment Processing API
version: 2.0.0
servers:
- url: https://api.payment.com/v2
description: Production
- url: https://sandbox.payment.com/v2
description: Sandbox
paths:
/payments:
post:
summary: Create a payment
requestBody:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/CreditCardPayment'
- $ref: '#/components/schemas/BankTransferPayment'
- $ref: '#/components/schemas/DigitalWalletPayment'
discriminator:
propertyName: paymentMethod
mapping:
credit_card: '#/components/schemas/CreditCardPayment'
bank_transfer: '#/components/schemas/BankTransferPayment'
digital_wallet: '#/components/schemas/DigitalWalletPayment'
examples:
creditCard:
summary: Credit card payment
value:
paymentMethod: credit_card
amount: 99.99
currency: USD
cardNumber: "4111111111111111"
expiryDate: "12/25"
cvv: "123"
bankTransfer:
summary: Bank transfer
value:
paymentMethod: bank_transfer
amount: 500.00
currency: EUR
iban: "DE89370400440532013000"
bic: "COBADEFFXXX"
responses:
'201':
description: Payment created
content:
application/json:
schema:
$ref: '#/components/schemas/PaymentResponse'
callbacks:
paymentStatus:
'{$request.body#/callbackUrl}':
post:
summary: Payment status update
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PaymentWebhook'
responses:
'200':
description: Webhook received
components:
schemas:
CreditCardPayment:
type: object
required: [paymentMethod, amount, currency, cardNumber]
properties:
paymentMethod:
type: string
const: credit_card
amount:
type: number
minimum: 0.01
currency:
type: string
pattern: "^[A-Z]{3}$"
cardNumber:
type: string
pattern: "^[0-9]{13,19}$"
expiryDate:
type: string
pattern: "^(0[1-9]|1[0-2])/[0-9]{2}$"
cvv:
type: string
pattern: "^[0-9]{3,4}$"
BankTransferPayment:
type: object
required: [paymentMethod, amount, currency, iban]
properties:
paymentMethod:
type: string
const: bank_transfer
amount:
type: number
currency:
type: string
iban:
type: string
bic:
type: string
DigitalWalletPayment:
type: object
required: [paymentMethod, amount, walletProvider, walletToken]
properties:
paymentMethod:
type: string
const: digital_wallet
amount:
type: number
walletProvider:
type: string
enum: [paypal, apple_pay, google_pay]
walletToken:
type: string
PaymentResponse:
type: object
properties:
id:
type: string
format: uuid
status:
type: string
enum: [pending, completed, failed]
createdAt:
type: string
format: date-time
PaymentWebhook:
type: object
properties:
eventType:
type: string
enum: [payment.completed, payment.failed]
paymentId:
type: string
timestamp:
type: string
format: date-time
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
OAuth2:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://auth.payment.com/oauth/authorize
tokenUrl: https://auth.payment.com/oauth/token
scopes:
payments:write: Create payments
payments:read: Read payment status
security:
- ApiKeyAuth: []
- OAuth2: [payments:write]
Diagrama
graph TB
subgraph "OpenAPI 3.x Features"
subgraph "Core Improvements"
SERVERS[Múltiples Servidores
Prod, Staging, Regional]
EXAMPLES[Múltiples Ejemplos
Por Content Type]
LINKS[Links
Encadenamiento de Operaciones]
end
subgraph "Schema Enhancements"
ONEOF[oneOf/anyOf/allOf
Composición]
DISC[Discriminador
Polimorfismo]
JSON[JSON Schema Completo
v2020-12 en 3.1]
end
subgraph "Advanced Patterns"
CALLBACK[Callbacks
Webhooks]
COOKIE[Cookie Auth
Parameters]
COMP[Componentes Reutilizables
Headers, Examples]
end
end
API[Definición de API] --> SERVERS
API --> EXAMPLES
API --> ONEOF
API --> CALLBACK
style JSON fill:#90EE90
style CALLBACK fill:#FFD700
style DISC fill:#87CEEB
Notas de Seguridad
CRÍTICO - …
Configuración y Validación:
- Define los esquemas de seguridad explícitamente en components.securitySchemes.
- Aplica seguridad a nivel global o por operación.
- Nunca expongas campos sensibles en ejemplos o valores por defecto.
Monitoreo y Protección:
- Usa nullable con precaución en schemas - afecta la validación.
- Valida firmas de webhooks usando extensiones personalizadas x-webhook-signature.
- Documenta límites de tasa usando headers x-ratelimit.
- Asegúrate de que los scopes de OAuth coincidan con los modelos de permisos reales.
Mejores Prácticas
- Usar discriminador para polimorfismo - Cuando oneOf representa diferentes tipos, agrega un discriminador para ayudar a los generadores de código
- Aprovechar múltiples ejemplos - Proporciona ejemplos del mundo real para cada escenario, no solo casos de éxito
- Definir callbacks para webhooks - Modela las cargas útiles de webhooks como callbacks para generar manejadores de eventos apropiados
- Reutilizar componentes extensivamente - Extrae schemas comunes, parámetros, respuestas, ejemplos a componentes
- Usar JSON Schema completamente en 3.1 - Aprovecha if/then/else, dependencias y validación avanzada
- Documentar flujos de autenticación - Especifica flujos OAuth, ubicaciones de API key y requisitos de seguridad claramente
- Versionar servidores apropiadamente - Usa /v1, /v2 en URLs de servidor en lugar de en paths
- Agregar operation IDs - Estos se convierten en nombres de métodos en SDKs, así que hazlos descriptivos
Errores Comunes
Mezclar características de 3.0 y 3.1: Usar características de JSON Schema de 3.1 (como prefixItems) en una spec 3.0 causa errores de validación. Apégate a una versión.
Ignorar discriminador: Definir oneOf sin discriminador hace más difícil la generación de código y los mensajes de error crípticos cuando la validación falla.
Abusar de anyOf: Usar anyOf cuando oneOf es correcto (tipos mutuamente exclusivos). anyOf significa “puede coincidir con múltiples schemas simultáneamente”, lo cual raramente es intencional para contratos de API.
Hardcodear URLs de servidor: Poner URLs específicas de entorno en código de ejemplo en lugar de usar el array servers. Las herramientas no pueden cambiar automáticamente de entorno.
Omitir callbacks para webhooks: Documentar cargas útiles de webhook en prosa en lugar de como callbacks apropiados significa que no hay generación automática de manejadores de webhooks.
No testear validez de la spec: Publicar specs sin ejecutarlas a través de validadores. OpenAPI 3.x tiene requisitos estrictos que difieren de 2.0.
Definiciones de seguridad incompletas: Definir securitySchemes pero olvidar aplicarlos vía la propiedad security a nivel raíz o de operación.