OpenAPI 3

Estándares Security Notes Jan 9, 2026 YAML
openapi api-specification standards json-schema callbacks webhooks

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

SECURITY NOTES

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

  1. Usar discriminador para polimorfismo - Cuando oneOf representa diferentes tipos, agrega un discriminador para ayudar a los generadores de código
  2. Aprovechar múltiples ejemplos - Proporciona ejemplos del mundo real para cada escenario, no solo casos de éxito
  3. Definir callbacks para webhooks - Modela las cargas útiles de webhooks como callbacks para generar manejadores de eventos apropiados
  4. Reutilizar componentes extensivamente - Extrae schemas comunes, parámetros, respuestas, ejemplos a componentes
  5. Usar JSON Schema completamente en 3.1 - Aprovecha if/then/else, dependencias y validación avanzada
  6. Documentar flujos de autenticación - Especifica flujos OAuth, ubicaciones de API key y requisitos de seguridad claramente
  7. Versionar servidores apropiadamente - Usa /v1, /v2 en URLs de servidor en lugar de en paths
  8. 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.

Estándares y RFCs

Términos Relacionados