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 数据协定清晰且稳健。