SDKs
Data transforms
When the shape of data on the wire differs from the shape SDK users should see, use the x-speakeasy-transform-from-api and x-speakeasy-transform-to-api extensions to bridge the gap automatically. These extensions apply jq expressions to transform data during serialization and deserialization, so SDK users work with a clean interface while the underlying API format is preserved.
Language support
Data transforms currently generate transform code for the Go target only. Other SDK targets (TypeScript, Python, Java, C#) will silently ignore these extensions.
When to use data transforms
Section titled “When to use data transforms”Data transforms are useful when:
- The API returns a response shape that could be cleaner for SDK consumers, such as deeply nested structures that should be flattened
- The API schema cannot be changed, but the SDK should present a better interface
- Fields need to be derived from other fields, such as combining
first_nameandlast_nameintodisplay_name
Extensions
Section titled “Extensions”Place these extensions on a schema in the OpenAPI spec, typically on request body or response schemas.
x-speakeasy-transform-from-api: Transforms data from the API response before the SDK user sees it.x-speakeasy-transform-to-api: Transforms data to the API request format before sending.
Both extensions can be used on the same schema when transforms are needed in both directions.
Format
Section titled “Format”The value must be a YAML mapping with a jq key:
x-speakeasy-transform-from-api: jq: '.your_expression_here'Note
The only supported transform type is jq. Invalid syntax produces a build error with the expression and the parse error.
Examples
Section titled “Examples”Copy a field
Section titled “Copy a field”components: schemas: Resource: type: object x-speakeasy-transform-from-api: jq: '. + { backup_id: .id }' properties: id: type: stringRename a field
Section titled “Rename a field”components: schemas: Resource: type: object x-speakeasy-transform-to-api: jq: '{ displayName: .name }' properties: name: type: stringAdd a derived field
Section titled “Add a derived field”components: schemas: User: type: object x-speakeasy-transform-from-api: jq: '. + { display_name: .first_name + " " + .last_name }' properties: first_name: type: string last_name: type: stringFlatten a nested structure
Section titled “Flatten a nested structure”components: schemas: Order: type: object x-speakeasy-transform-from-api: jq: '. + { status: .metadata.status } | del(.metadata)' properties: id: type: string metadata: type: object properties: status: type: stringConditional field addition
Section titled “Conditional field addition”components: schemas: Account: type: object x-speakeasy-transform-from-api: jq: 'if .status == "active" then . + { is_active: true } else . end' properties: status: type: stringRemove a field before sending
Section titled “Remove a field before sending”components: schemas: UpdateRequest: type: object x-speakeasy-transform-to-api: jq: 'del(.internal_field)' properties: name: type: string internal_field: type: stringBidirectional transforms
Section titled “Bidirectional transforms”Apply both extensions on the same schema to transform data in both directions:
components: schemas: Service: type: object x-speakeasy-transform-to-api: jq: '{ displayName: .name, maxInstances: .max_instance_count }' x-speakeasy-transform-from-api: jq: '. + { name: .displayName, max_instance_count: .maxInstances }' properties: displayName: type: string maxInstances: type: integerConvert an array to a map
Section titled “Convert an array to a map”Transform arrays from the API into a simpler map structure:
requestBody: content: application/json: schema: type: object x-speakeasy-transform-to-api: jq: | .tags |= ( if type == "object" then to_entries | map({key: .key, value: .value}) else . end ) properties: tags: type: array items: type: object properties: key: type: string value: type: stringBuild composite identifiers
Section titled “Build composite identifiers”Create combined identifiers from separate API fields:
responses: "200": content: application/json: schema: type: object x-speakeasy-transform-from-api: jq: | .id = "projects/\(.project_id)/regions/\(.region)/databases/\(.name)" properties: project_id: type: string region: type: string name: type: string