Skip to content

Commit 9406a5b

Browse files
committed
Sync open source content 🐝 (from badf2d00655bd0c9ad72eebc320cd5316b6d8445)
1 parent 78e876a commit 9406a5b

File tree

4 files changed

+217
-2
lines changed

4 files changed

+217
-2
lines changed

_meta.global.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ const meta = {
288288
"oneof-schemas": {
289289
title: "OneOf",
290290
},
291+
"allof-schemas": {
292+
title: "AllOf",
293+
},
291294
"complex-numbers": {
292295
title: "Complex Numbers",
293296
},
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
---
2+
title: "OpenAPI: AllOf schemas"
3+
description: "Configure how `allOf` constructs are merged with deep or shallow merge strategies."
4+
slug: "/customize-sdks/allof-schemas/"
5+
---
6+
7+
import { Callout } from "@/mdx/components";
8+
9+
# The `allOf` keyword
10+
11+
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.
12+
13+
## Merge strategies
14+
15+
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.
16+
17+
```yaml
18+
generation:
19+
schemas:
20+
allOfMergeStrategy: deepMerge # or shallowMerge
21+
```
22+
23+
### Available strategies
24+
25+
**`deepMerge` (default for new SDKs)**: Recursively merges nested properties within objects, preserving properties from all schemas in the `allOf` array.
26+
27+
**`shallowMerge` (legacy behavior)**: Replaces entire property blocks when merging, which can result in lost properties from earlier schemas.
28+
29+
<Callout title="Default behavior" type="info">
30+
New SDKs default to `deepMerge`. Existing SDKs continue to use `shallowMerge` unless explicitly changed. Switching from `shallowMerge` to `deepMerge` may be a breaking change for existing SDKs.
31+
</Callout>
32+
33+
## Deep merge behavior
34+
35+
With `deepMerge` enabled, nested properties are recursively combined rather than replaced. This is particularly useful when extending base schemas with additional nested properties.
36+
37+
Consider this OpenAPI definition:
38+
39+
```yaml
40+
components:
41+
schemas:
42+
Base:
43+
type: object
44+
properties:
45+
id:
46+
type: string
47+
metadata:
48+
type: object
49+
properties:
50+
createdAt:
51+
type: string
52+
updatedAt:
53+
type: string
54+
Extended:
55+
allOf:
56+
- $ref: '#/components/schemas/Base'
57+
- type: object
58+
properties:
59+
name:
60+
type: string
61+
metadata:
62+
type: object
63+
properties:
64+
deletedAt:
65+
type: string
66+
```
67+
68+
With `deepMerge`, the resulting merged schema preserves all metadata properties:
69+
70+
```yaml
71+
components:
72+
schemas:
73+
Extended:
74+
type: object
75+
properties:
76+
id:
77+
type: string
78+
metadata:
79+
type: object
80+
properties:
81+
createdAt:
82+
type: string
83+
updatedAt:
84+
type: string
85+
deletedAt:
86+
type: string
87+
name:
88+
type: string
89+
```
90+
91+
The `metadata` object includes all three timestamp properties: `createdAt`, `updatedAt`, and `deletedAt`.
92+
93+
## Shallow merge behavior
94+
95+
With `shallowMerge`, entire property blocks are replaced during merging. When the same property name appears in multiple schemas, only the last occurrence is retained.
96+
97+
Using the same example from above with `shallowMerge`:
98+
99+
```yaml
100+
components:
101+
schemas:
102+
Extended:
103+
type: object
104+
properties:
105+
id:
106+
type: string
107+
metadata:
108+
type: object
109+
properties:
110+
deletedAt:
111+
type: string
112+
name:
113+
type: string
114+
```
115+
116+
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.
117+
118+
## Configuration
119+
120+
To configure the merge strategy, add the `schemas.allOfMergeStrategy` option to the `generation` section of the `gen.yaml` file:
121+
122+
```yaml
123+
generation:
124+
schemas:
125+
allOfMergeStrategy: deepMerge
126+
```
127+
128+
### Switching strategies
129+
130+
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.
131+
132+
To explicitly use the legacy behavior:
133+
134+
```yaml
135+
generation:
136+
schemas:
137+
allOfMergeStrategy: shallowMerge
138+
```
139+
140+
## Use cases
141+
142+
### Deep merge use cases
143+
144+
Deep merge is beneficial when:
145+
146+
- Extending base schemas with additional nested properties
147+
- Combining request and response schemas with shared metadata objects
148+
- Working with APIs that use `allOf` to compose complex nested structures
149+
- Maintaining all properties across schema inheritance hierarchies
150+
151+
### Shallow merge use cases
152+
153+
Shallow merge may be appropriate when:
154+
155+
- Maintaining backward compatibility with existing SDKs
156+
- Intentionally replacing entire nested objects from base schemas
157+
- Working with simple schema compositions without nested property conflicts
158+
159+
## Advanced example
160+
161+
This pattern is common in APIs that separate shared components from operation-specific requirements and examples:
162+
163+
```yaml
164+
paths:
165+
/clusters:
166+
post:
167+
operationId: createCluster
168+
requestBody:
169+
content:
170+
application/json:
171+
schema:
172+
allOf:
173+
- $ref: '#/components/schemas/Cluster'
174+
- type: object
175+
required:
176+
- spec
177+
properties:
178+
spec:
179+
type: object
180+
required:
181+
- displayName
182+
- availability
183+
- type: object
184+
properties:
185+
spec:
186+
type: object
187+
properties:
188+
environment:
189+
example: { id: 'env-00000' }
190+
network:
191+
example: { id: 'n-00000' }
192+
```
193+
194+
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.
195+
196+
With `shallowMerge`, the `spec` properties from the second schema would be lost entirely, replaced by only the example properties from the third schema.

docs/speakeasy-reference/generation/gen-yaml.mdx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Callout } from "@/mdx/components";
77

88
For most use cases, the `speakeasy configure` command is the recommended means of interacting with the Speakeasy `gen.yaml` file. The `speakeasy configure` command has subcommands for configuring sources, targets, GitHub workflow setups, and package publications. All new targets created using `speakeasy quickstart` automatically generate workflow files in the `.speakeasy/` folder in the root of the target directory.
99
<br/>
10-
The <Image src="/assets/vscode.svg" alt="VS Code" width="20" height="20" style={{display: "inline-block", verticalAlign: "middle"}} /> [Speakeasy VS Code extension](https://marketplace.visualstudio.com/items?itemName=Speakeasy.speakeasy-vscode-extension) provides several useful features for manually editing the `gen.yaml` file, including syntax highlighting, autocompletion, and linting for OpenAPI documents and other supported file types.
10+
The <Image src="/assets/vscode.svg" alt="VS Code" width="20" height="20" className="inline-block! w-auto! size-5 mx-2! my-0" /> [Speakeasy VS Code extension](https://marketplace.visualstudio.com/items?itemName=Speakeasy.speakeasy-vscode-extension) provides several useful features for manually editing the `gen.yaml` file, including syntax highlighting, autocompletion, and linting for OpenAPI documents and other supported file types.
1111

1212
</Callout>
1313

@@ -163,3 +163,19 @@ Disables the generation and use of a mock HTTP server with generated tests.
163163
mockServer:
164164
disabled: true
165165
```
166+
167+
### schemas
168+
169+
Configuration for how OpenAPI schemas are processed during SDK generation.
170+
171+
#### allOfMergeStrategy
172+
173+
Controls how `allOf` constructs in OpenAPI schemas are merged. For detailed information about merge strategies, see the [allOf schemas documentation](/docs/customize/data-model/allof-schemas).
174+
175+
- `deepMerge` (default for new SDKs): Recursively merges nested properties within objects, preserving properties from all schemas in the `allOf` array.
176+
- `shallowMerge` (legacy behavior): Replaces entire property blocks when merging, which can result in lost properties from earlier schemas.
177+
178+
```yaml
179+
schemas:
180+
allOfMergeStrategy: deepMerge
181+
```

docs/speakeasy-reference/workflow-file.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ For most use cases we recommend interacting with the Speakeasy workflow file (`w
1414
This command has subcommands to configure sources, targets, github setup and package publishing. All new targets created through `speakeasy quickstart` will automatically have a workflow
1515
file created in the `.speakeasy/` folder in the root of their target directory.
1616
<br/>
17-
For editing the workflow file manually, <Image src="/assets/vscode.svg" alt="VS Code" width="20" height="20" style={{display: "inline-block", verticalAlign: "middle"}} /> [Speakeasy's VSCode extension](https://marketplace.visualstudio.com/items?itemName=Speakeasy.speakeasy-vscode-extension) provides syntax highlighting and autocompletion for the workflow file,
17+
For editing the workflow file manually, <Image src="/assets/vscode.svg" alt="VS Code" width="20" height="20" className="inline-block! w-auto! size-5 mx-2! my-0" /> [Speakeasy's VSCode extension](https://marketplace.visualstudio.com/items?itemName=Speakeasy.speakeasy-vscode-extension) provides syntax highlighting and autocompletion for the workflow file,
1818
in addition to linting for OpenAPI documents, and our other supported file types.
1919

2020
</Callout>

0 commit comments

Comments
 (0)