The oneOf keyword
In support of the OpenAPI Specification oneOf schemas, Speakeasy SDKs provide language-specific implementations based on idiomatic unions (when available) or using generated supporting objects that allow type safety by using an enum discriminator.
Supporting objects
Assuming an OpenAPI document has a Pet component, consider this oneOf block:
oneOf:
- type: string
- type: integer
- $ref: "/components/schemas/Pet"How Speakeasy generates supporting objects for your SDK depends on the language of the SDK.
Requests
Assume you have an operation that allows the user to fetch a pet by submitting the pet’s name, ID, or complete pet object:
/pet:
get:
operationId: fetchPet
requestBody:
description: identifier of pet to fetch
required: true
content:
application/json:
schema:
oneOf:
- type: string
- type: integer
- $ref: "/components/schemas/Pet"
responses:
"200":
description: fetched pet
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"Responses
Sometimes you may have a response that specifies a oneOf schema. For languages that do not natively support unions, Speakeasy will create supporting objects to deserialize the oneOf response into the correct object type. No supported objects are needed for languages with native union types, so Speakeasy will deserialize into the native type.
For example, this schema:
/pet_id:
get:
operationId: petId
responses:
"200":
description: OK
content:
application/json:
schema:
title: res
oneOf:
- type: string
- type: integerWill result in these response types:
Discriminator display names
When a oneOf schema uses a discriminator with mapping keys that contain special characters (e.g., $login, $challenge), the generated SDK identifiers can become unwieldy. For example, a $login key produces a Go function named CreateRiskDollarLogin because the $ character is sanitized to Dollar.
The x-speakeasy-discriminator extension provides clean display names for discriminator mapping keys while preserving the original values for JSON serialization.
components:
schemas:
RiskAssessment:
oneOf:
- $ref: "#/components/schemas/LoginRiskRequest"
- $ref: "#/components/schemas/ChallengeRiskRequest"
discriminator:
propertyName: type
mapping:
$login: "#/components/schemas/LoginRiskRequest"
$challenge: "#/components/schemas/ChallengeRiskRequest"
x-speakeasy-discriminator:
$login: login
$challenge: challengeIn this example, the generated Go SDK uses CreateRiskAssessmentLogin and CreateRiskAssessmentChallenge as function names instead of CreateRiskAssessmentDollarLogin and CreateRiskAssessmentDollarChallenge. The wire values ("$login" and "$challenge") remain unchanged during JSON serialization.
The extension maps each discriminator mapping key to a display name. Only keys that need renaming must be included. Any key not listed in x-speakeasy-discriminator retains its original name for identifier generation.
This extension is supported in Go, Terraform, and mock server targets.
Splitting oneOf schema types
By defining similar operations with aligned but different schemas, you can apply x-speakeasy-type-override: any for untyped operations and use oneOf to define stricter types in others. This allows you to use methods like DoSomething(StrictObject{...}) alongside DoSomethingUntyped({...}), providing flexibility across SDK methods based on the required schema type.
This approach is particularly useful when dealing with endpoints that require you to split oneOf schema types into separate SDK methods.
Example:
/sources#SellerPartner:
post:
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/SourceSellerPartnerCreateRequest"
tags:
- "Sources"
responses:
"200":
content:
application/json:
schema:
$ref: "#/components/schemas/SourceResponse"
description: "Successful operation"
"400":
description: "Invalid data"
"403":
description: "Not allowed"
operationId: "createSourceSellerPartner"
summary: "Create a source"
description: "Creates a source given a name, workspace ID, and a JSON blob containing the configuration for the source."
x-speakeasy-entity-operation: Source_SellerPartner#createLast updated on