# oneOf, allOf, anyOf

# oneOf, allOf, anyOf: composition and inheritance in OpenAPI

OpenAPI allows us to combine object schemas using the keywords `allOf`, `anyOf`, and `oneOf`.

These keywords correspond to the following logical operators:

The example below illustrates the different composition keywords:

```yaml
components:
  schemas:
    # ... Other schemas ...
    Negroni:
      description: A Negroni cocktail. Contains gin, vermouth and campari.
      allOf:
        - $ref: "#/components/schemas/Vermouth"
        - $ref: "#/components/schemas/Gin"
        - $ref: "#/components/schemas/Campari"
    Martini:
      description: A Martini cocktail. Contains gin and vermouth, or vodka and vermouth.
      oneOf:
        - $ref: "#/components/schemas/Vodka"
        - $ref: "#/components/schemas/Gin"
      - $ref: "#/components/schemas/Vermouth"
    Punch:
      description: A Punch cocktail. Contains any combination of alcohol.
      anyOf:
        - $ref: "#/components/schemas/Rum"
        - $ref: "#/components/schemas/Brandy"
        - $ref: "#/components/schemas/Whisky"
        - $ref: "#/components/schemas/Vodka"
        - $ref: "#/components/schemas/Gin"
```

## Discriminator Object in OpenAPI

When using `oneOf` to indicate that a request body or response contains exactly one of multiple [Schema Objects](/openapi/schemas), a discriminator object can help the client or server figure out which schema is included in the request or response.

The discriminator object in OpenAPI tells a client or server which field can be used to discriminate between different schemas.

In the example below, the Speakeasy Bar can receive one of two order types: A drink order with a bar-counter reference or an ingredient order with a delivery address:

```yaml
components:
  responses:
    OrderResponse:
      oneOf:
        - $ref: "#/components/schemas/DrinkOrder"
        - $ref: "#/components/schemas/IngredientOrder"
```

If we include a discriminator object, the client can indicate the order type so that the server does not need to figure that out:

```yaml
components:
  responses:
    OrderResponse:
      oneOf:
        - $ref: "#/components/schemas/DrinkOrder"
        - $ref: "#/components/schemas/IngredientOrder"
      discriminator:
        propertyName: orderType
```

In the previous example, the value of the `orderType` property will determine the order type. The value of `orderType` must match one of the schema components, so must be either `DrinkOrder` or `IngredientOrder`.

To use values that don't match a schema key, a discriminator object can include a `mapping` property that maps values to schemas. Here's an example:

```yaml
components:
  responses:
    OrderResponse:
      oneOf:
        - $ref: "#/components/schemas/DrinkOrder"
        - $ref: "#/components/schemas/IngredientOrder"
      discriminator:
        propertyName: orderType
        mapping:
          drink: "#/components/schemas/DrinkOrder"
          ingredient: "#/components/schemas/IngredientOrder"
```
