¿Cómo gestiona OpenAPI los tipos de datos complejos?

¿Cómo gestiona OpenAPI los tipos de datos complejos? #

La especificación OpenAPI (OAS) es, sin duda, una herramienta fundamental en el mundo de las API. Define una interfaz estándar e independiente del lenguaje para las API REST, que permite a personas y equipos informáticos comprender las capacidades del servicio sin acceder al código fuente, a documentación adicional ni a la inspección del tráfico de red. La gestión de tipos de datos complejos en OpenAPI es una característica clave que aumenta su utilidad y permite diseños de API más elaborados y sólidos.

En este artículo exploraremos cómo gestiona OpenAPI los tipos de datos complejos, las estrategias y prácticas que emplea, y ejemplos que ilustran su capacidad para dar forma a API bien definidas, versátiles y escalables.

Comprender los tipos de datos en OpenAPI #

Antes de profundizar en los tipos de datos complejos, es importante conocer los tipos de datos básicos que admite OpenAPI. OpenAPI especifica los siguientes tipos de datos primitivos:

  1. String (cadena)
  2. Number (número)
  3. Integer (entero)
  4. Boolean (booleano)
  5. Array (arreglo)
  6. Object (objeto)

Estos son los bloques fundamentales sobre los que se construyen las estructuras de datos más complejas.

Tipos primitivos #

  • String: representa datos textuales.
  • Number: representa cualquier valor numérico.
  • Integer: representa valores numéricos sin componente fraccionario.
  • Boolean: representa valores binarios (true o false).
  • Array: representa una lista de elementos en la que cada elemento puede ser de cualquier tipo.
  • Object: representa una colección de pares clave-valor.

Gestión de tipos de datos complejos #

Los tipos de datos complejos combinan estos tipos primitivos para crear representaciones de datos más sofisticadas y estructuradas. Los principales medios para gestionar tipos de datos complejos en OpenAPI son los arreglos (arrays) y los objetos.

Arreglos de tipos complejos #

Un arreglo puede contener objetos u otros arreglos, lo que da lugar a estructuras de datos anidadas y elaboradas. Para definir un arreglo de objetos, especifica el type como array y usa la propiedad items para definir el objeto contenido en el arreglo.

components:
  schemas:
    Pet:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string

    Pets:
      type: array
      items:
        $ref: '#/components/schemas/Pet'

En el ejemplo anterior, Pets es un arreglo de objetos Pet.

Objetos #

Los objetos en OpenAPI se definen como los objetos JSON, con propiedades que se asignan a cada par clave-valor. Puedes anidar objetos para crear estructuras complejas.

components:
  schemas:
    Address:
      type: object
      properties:
        street:
          type: string
        city:
          type: string
        state:
          type: string
        zipCode:
          type: string

    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
        address:
          $ref: '#/components/schemas/Address'

En este ejemplo, el objeto User contiene una propiedad address, que hace referencia a otro objeto definido en schemas.

Objetos anidados #

OpenAPI permite anidar objetos dentro de otros objetos, lo que posibilita representar estructuras de datos jerárquicas y con muchos niveles de anidamiento. A continuación se muestra un ejemplo:

components:
  schemas:
    OrderItem:
      type: object
      properties:
        productId:
          type: integer
        quantity:
          type: integer
        price:
          type: number
          format: float

    Order:
      type: object
      properties:
        orderId:
          type: integer
        customerId:
          type: integer
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrderItem'

Aquí, el objeto Order contiene un arreglo anidado de objetos OrderItem.

AllOf, AnyOf, OneOf y Not #

Para gestionar escenarios de validación más complejos, OpenAPI ofrece las construcciones allOf, anyOf, oneOf y not. Estas construcciones combinan esquemas para crear estructuras compuestas.

  • allOf combina varios esquemas y valida el objeto frente a todos ellos.
  • anyOf valida el objeto frente a cualquiera de los esquemas.
  • oneOf garantiza que el objeto sea válido frente a uno y solo uno de los esquemas.
  • not garantiza que el objeto no se valide frente al esquema.

Ejemplo de allOf #

components:
  schemas:
    Pet:
      type: object
      properties:
        name:
          type: string
        age:
          type: integer

    IdentifiedPet:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            id:
              type: integer

IdentifiedPet combina las propiedades de Pet y añade una propiedad id.

Ejemplo de anyOf #

components:
  schemas:
    Student:
      type: object
      properties:
        studentId:
          type: string

    Teacher:
      type: object
      properties:
        employeeId:
          type: string

    Person:
      anyOf:
        - $ref: '#/components/schemas/Student'
        - $ref: '#/components/schemas/Teacher'

Un Person puede ser un Student o un Teacher.

Polimorfismo #

OpenAPI admite el polimorfismo, que permite definir esquemas capaces de representar varios tipos. Resulta especialmente útil para diseñar API que deben trabajar con entidades variadas que comparten campos comunes.

Discriminator #

Un discriminator ayuda a OpenAPI a determinar qué esquema usar según el valor de una propiedad específica. Es una forma de gestionar una especie de herencia o, dicho de otro modo, modelos polimórficos en las API.

components:
  schemas:
    Pet:
      type: object
      required:
        - petType
      properties:
        petType:
          type: string
      discriminator:
        propertyName: petType

    Cat:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            petType:
              type: string
              enum: [cat]
            huntingSkill:
              type: string
              enum: [clueless, lazy, adventurous, aggressive]

    Dog:
      allOf:
        - $ref: '#/components/schemas/Pet'
        - type: object
          properties:
            petType:
              type: string
              enum: [dog]
            packSize:
              type: integer

En el ejemplo, Pet es un esquema base, y Cat y Dog son esquemas especializados. La propiedad discriminator ayuda a OpenAPI a determinar si Pet es un Cat o un Dog a partir de la propiedad petType.

Adición de metadatos y restricciones #

OpenAPI permite añadir metadatos y restricciones a los esquemas para aplicar reglas y proporcionar información adicional.

Ejemplos #

components:
  schemas:
    Product:
      type: object
      properties:
        id:
          type: integer
          description: The unique identifier for a product.
        name:
          type: string
          description: Name of the product.
          minLength: 2
          maxLength: 50
        price:
          type: number
          format: float
          description: Price of the product.
          minimum: 0

En este ejemplo se imponen varias restricciones, como minLength, maxLength y minimum.

Herramientas y bibliotecas compatibles con OpenAPI #

Varias herramientas y bibliotecas son compatibles con la especificación OpenAPI y ayudan en el diseño, la documentación y el desarrollo de API. Algunas de las más destacadas son:

  • Swagger Editor: un proyecto de código abierto que permite diseñar API con OpenAPI.
  • Swagger UI: muestra las especificaciones OpenAPI como documentación interactiva de la API.
  • API Gateway: AWS API Gateway permite importar definiciones OpenAPI para crear API sin esfuerzo.
  • Postman: Postman puede importar especificaciones OpenAPI, lo que permite probar los endpoints de la API.

Conclusión #

OpenAPI gestiona los tipos de datos complejos con soltura, ya que ofrece mecanismos como objetos, arreglos, allOf, anyOf, oneOf, not y discriminadores para estructurar esquemas de datos intrincados. Estas capacidades garantizan que las definiciones de la API sean claras y completas, y que se apliquen reglas estrictas de tipado y validación. Gracias a un sólido soporte de herramientas, OpenAPI sigue a la vanguardia de los estándares de las API y permite un diseño y una implementación de API coherentes y escalables.


Última actualización: 21 de mayo de 2024.

Este sitio web no está afiliado a la OpenAPI Initiative.