Speakeasy Logo
Skip to Content

The allOf keyword

The OpenAPI allOf keyword enables schema composition by merging multiple schema definitions into a single schema. Speakeasy provides two strategies for handling allOf merging: shallow merge and deep merge.

Merge strategies

The schemas.allOfMergeStrategy configuration option in gen.yaml controls how Speakeasy merges allOf schemas. This setting is located under the generation section of the configuration file.

generation: schemas: allOfMergeStrategy: deepMerge # or shallowMerge

Available strategies

deepMerge (default for new SDKs): Recursively merges nested properties within objects, preserving properties from all schemas in the allOf array.

shallowMerge (legacy behavior): Replaces entire property blocks when merging, which can result in lost properties from earlier schemas.

Deep merge behavior

With deepMerge enabled, nested properties are recursively combined rather than replaced. This is particularly useful when extending base schemas with additional nested properties.

Consider this OpenAPI definition:

components: schemas: Base: type: object properties: id: type: string metadata: type: object properties: createdAt: type: string updatedAt: type: string Extended: allOf: - $ref: '#/components/schemas/Base' - type: object properties: name: type: string metadata: type: object properties: deletedAt: type: string

With deepMerge, the resulting merged schema preserves all metadata properties:

components: schemas: Extended: type: object properties: id: type: string metadata: type: object properties: createdAt: type: string updatedAt: type: string deletedAt: type: string name: type: string

The metadata object includes all three timestamp properties: createdAt, updatedAt, and deletedAt.

Shallow merge behavior

With shallowMerge, entire property blocks are replaced during merging. When the same property name appears in multiple schemas, only the last occurrence is retained.

Using the same example from above with shallowMerge:

components: schemas: Extended: type: object properties: id: type: string metadata: type: object properties: deletedAt: type: string name: type: string

The metadata properties createdAt and updatedAt from the Base schema are lost because the entire metadata properties block was replaced by the one in the Extended schema.

Configuration

To configure the merge strategy, add the schemas.allOfMergeStrategy option to the generation section of the gen.yaml file:

generation: schemas: allOfMergeStrategy: deepMerge

Switching strategies

Changing from shallowMerge to deepMerge may affect the generated SDK’s type definitions and could be a breaking change. Review the impact on existing generated code before making this change in production SDKs.

To explicitly use the legacy behavior:

generation: schemas: allOfMergeStrategy: shallowMerge

Use cases

Deep merge use cases

Deep merge is beneficial when:

  • Extending base schemas with additional nested properties
  • Combining request and response schemas with shared metadata objects
  • Working with APIs that use allOf to compose complex nested structures
  • Maintaining all properties across schema inheritance hierarchies

Shallow merge use cases

Shallow merge may be appropriate when:

  • Maintaining backward compatibility with existing SDKs
  • Intentionally replacing entire nested objects from base schemas
  • Working with simple schema compositions without nested property conflicts

Advanced example

This pattern is common in APIs that separate shared components from operation-specific requirements and examples:

paths: /clusters: post: operationId: createCluster requestBody: content: application/json: schema: allOf: - $ref: '#/components/schemas/Cluster' - type: object required: - spec properties: spec: type: object required: - displayName - availability - type: object properties: spec: type: object properties: environment: example: { id: 'env-00000' } network: example: { id: 'n-00000' }

With deepMerge, the final spec object combines the required fields from the second schema with the examples from the third schema, while preserving all properties from the referenced Cluster component.

With shallowMerge, the spec properties from the second schema would be lost entirely, replaced by only the example properties from the third schema.

Last updated on