OneOf、anyOf、allOf 介紹

APIGit

2024-03-15

api-one-all-any

在使用 OpenAPI 規範 (OAS) 設計或記錄 API 時,您經常會遇到描述複雜資料結構的需求。這些結構可能需要定義各種場景,例如針對不同條件的不同物件結構、將多個物件組合為一個對象,或指定一個物件可以匹配多種類型中的任何一種。這是哪裡oneOf,allOf, 和anyOf 閃耀,提供這些任務所需的靈活性和精度。

理解allOf

allOf 用於將多個模式組合成一個模式,其中包括組合模式中的所有屬性。當您想要建立一個從多個其他模式繼承屬性的複雜模式時,它特別有用。

例如,如果您有一個Person 具有常見屬性的模式,例如nameage,和一個Student 架構應包含以下所有屬性Person 多於studentId, 您可以使用allOf 來創建Student 架構而不重複Person 特性。

components:
  schemas:
    Person:
      type: object
      properties:
        name:
          type: string
        age:
          type: integer
    Student:
      allOf:
        - $ref: '#/components/schemas/Person'
        - type: object
          properties:
            studentId:
              type: string

探索oneOf

oneOf 指定資料應與引用的模式之一完全匹配。它對於為資料物件定義不同的可能結構非常有用,其中只有一種結構對於任何給定實例有效。

考慮一個接受付款方式的 API 端點,該付款方式可以是信用卡或銀行帳戶,但不能同時是兩者。使用oneOf,您可以清楚地定義這些選項:

components:
  schemas:
    CreditCard:
      type: object
      properties:
        number:
          type: string
        expiryDate:
          type: string
        cvv:
          type: string
    BankAccount:
      type: object
      properties:
        accountNumber:
          type: string
        routingNumber:
          type: string
    PaymentMethod:
      oneOf:
        - $ref: '#/components/schemas/CreditCard'
        - $ref: '#/components/schemas/BankAccount'

破解anyOf

anyOf 允許資料匹配任何(一個或多個)引用的模式。當資料可以採用多種形式時,它提供了靈活性,並且不需要像oneOf

例如,如果 API 端點接受contact 物件可以是phone number, 一個email address或兩者,您可以使用anyOf 來表示這個:

components:
  schemas:
    PhoneNumber:
      type: object
      properties:
        phone:
          type: string
    EmailAddress:
      type: object
      properties:
        email:
          type: string
    Contact:
      anyOf:
        - $ref: '#/components/schemas/PhoneNumber'
        - $ref: '#/components/schemas/EmailAddress'

結論

allOf,oneOf, 和anyOf 關鍵字為 OpenAPI 規範添加了必要的多功能性,從而可以定義複雜且細緻入微的資料模型。透過有效地理解和使用這些工具,API 設計者和文件編制者可以創建更準確、更靈活的 API 規範。無論您是繼承屬性、指定獨佔類型還是允許多個結構,這些關鍵字都可確保您的 API 資料協定清晰且穩健。