पाठ 8 / 25

Reuse and Composition: $ref, allOf, oneOf, anyOf and Discriminators

Reuse schemas and model inheritance and alternatives.

Building complex models from parts

Define schemas once under components/schemas and reference them with $ref: '#/components/schemas/Order', or reference other files ($ref: './schemas/order.yaml'). Composition keywords combine schemas. allOf: the value must satisfy all listed schemas, used to extend a base schema (a PhysicalProduct is a Product plus weight). oneOf: the value must match exactly one schema, used for alternatives such as payment methods (UPI, card or net banking). anyOf: the value must match at least one. not excludes a schema. For oneOf polymorphism, add a discriminator naming the property that tells variants apart (method), optionally with a mapping from values to schemas; code generators use it to create subtypes and deserialise correctly. Keep composition simple: deeply nested allOf/oneOf chains confuse readers and many generators. Note that oneOf requires exactly one match, so overlapping variants (both accepting the same data) fail validation; make variants distinguishable with required fields or const values.

Polymorphic payment methods with a discriminator

Each variant is distinguishable by its method value.

components:
  schemas:
    PaymentMethod:
      oneOf:
        - $ref: '#/components/schemas/UpiPayment'
        - $ref: '#/components/schemas/CardPayment'
        - $ref: '#/components/schemas/NetBankingPayment'
      discriminator:
        propertyName: method
        mapping:
          UPI: '#/components/schemas/UpiPayment'
          CARD: '#/components/schemas/CardPayment'
          NETBANKING: '#/components/schemas/NetBankingPayment'

    PaymentBase:
      type: object
      required: [method, amountInr]
      properties:
        method: { type: string }
        amountInr: { type: string, pattern: '^\d+\.\d{2}$' }

    UpiPayment:
      allOf:
        - $ref: '#/components/schemas/PaymentBase'
        - type: object
          required: [vpa]
          properties:
            method: { const: UPI }
            vpa: { type: string, examples: ['asha@okbank'] }

    CardPayment:
      allOf:
        - $ref: '#/components/schemas/PaymentBase'
        - type: object
          required: [cardToken]
          properties:
            method: { const: CARD }
            cardToken: { type: string, description: Token from the card vault, never a raw card number }

    NetBankingPayment:
      allOf:
        - $ref: '#/components/schemas/PaymentBase'
        - type: object
          required: [bankCode]
          properties:
            method: { const: NETBANKING }
            bankCode: { type: string }

A form with sections that depend on a tick box

A payment form shows UPI fields if you tick UPI, card fields if you tick card. oneOf with a discriminator is that form: the ticked box decides which section must be filled in.

त्वरित जाँच: Which composition keyword requires a value to match exactly one of several schemas?

  • allOf
  • anyOf
  • not
  • oneOf
Answer

oneOf — oneOf succeeds only when exactly one alternative validates.