Endpoint migration
Glotto detects breaking changes for you (how). Endpoint migration is the other half: how to avoid one.
When you rename or re-version an endpoint, the generated SDK method changes with it — and every
one of your users’ call sites stops compiling. Two glotto.yml blocks let you make that change
without shipping a major version.
aliases — keep the old method name working
aliases:
createRecord: upsertRecord
An alias keeps a method name in the SDK and routes it to the operation you name. The key is the
name your users already call; the value is the operationId it should now resolve to.
Glotto materializes the alias as a real method cloned from its target, so it issues the target’s request — the new endpoint, not the removed one:
// Both exist. `createRecord` issues PUT /v1/records, exactly like upsertRecord.
await client.records.upsertRecord({ id: 'rec_1', name: 'Ada' });
await client.records.createRecord({ id: 'rec_1', name: 'Ada' });
Because the alias re-occupies the method the rename vacated, breaking-change detection reports no breaking change for it. The renamed operation still shows up — as a non-breaking addition.
Alias names are resolved against your spec, so an entry whose target doesn’t exist is ignored
rather than failing the build. That is what lets one config describe both sides of a diff: when
breaking-changes builds your previous spec, the new target isn’t there yet, no alias
materializes, and the old operation is simply still present.
deprecated — tell callers where to go
deprecated:
createRecord: Use upsertRecord instead.
A plain string is the message for every language. To vary it — method names differ across
languages — use the object form, which takes a required default plus per-target overrides:
deprecated:
createRecord:
default: Use upsertRecord instead.
python: Use upsert_record() instead.
go: Use UpsertRecord instead.
default is required so every language always has message text; several targets have no
message-less deprecation form.
Each SDK renders it in that language’s own construct, so your users get the warning from their own compiler or editor rather than from release notes:
| Language | Emitted |
|---|---|
| TypeScript, React Native | @deprecated JSDoc |
| Python | Deprecated: docstring line |
| Go | // Deprecated: (the godoc convention) |
| Java | @Deprecated + @deprecated javadoc |
| Kotlin | @Deprecated("…") |
| C# | [Obsolete("…")] |
| PHP | @deprecated docblock |
| Ruby | # @deprecated (YARD) |
| Rust | #[deprecated(note = "…")] |
| Swift | @available(*, deprecated, message: "…") |
| Dart | @Deprecated('…') |
| Elixir | @deprecated "…" |
Deprecation is compile-time and documentation-time only — nothing is added to the request path, so a deprecated call costs your users nothing at runtime.
Putting them together
The two blocks are independent maps keyed the same way, so you can deprecate an alias — which is the usual migration shape: the old name keeps working and warns.
examples/endpoint-migration/inputs — every byte below is sliced from that demo or from one real generate run over it. What Glotto emits — a real method, cloned from its target
typescript/src/resources/v1-records.ts V1RecordsResource.createRecord
/**
* Alias of `upsertRecord`.
* @deprecated Use upsertRecord instead.
*/
createRecord(params: RecordModel, options?: RequestOptions): Promise<RecordModel> {
return this.core.request<RecordModel>('PUT', '/v1/records', { ...options, body: params, contentType: 'application/json' });
} 40eab644eedff65fc7e54714906e8f3d463bbc7540c0ad8021ba3c30f90cdd2a Re-versioning — when the path moves too
The alias above is materialized in its target’s resource, which is right whenever the rename
leaves the path alone. But Glotto derives the resource tree from your URLs, so a rename that also
moves the path — /v1/exports → /v2/exports — moves the resource with it. The SDK surface your
users call (exports.createExport(...) under v1) is then somewhere your current spec no longer
describes, and no amount of reading that spec can find it.
Say where it used to live, and the alias works exactly as before:
aliases:
createExport:
target: createExportV2
path: /v1/exports
path is the path the superseded method was served at. Glotto derives its resource from that
path with the same rule it uses for every other path in your spec, so the alias reoccupies exactly
the surface the move vacated — and breaking-changes reports no breaking change, same as the
in-place rename.
path places the method; it never routes it. The alias still issues the target’s request:
// Still under the v1 surface your users already call — and it POSTs /v2/exports.
await client.v1.exports.createExport({ format: 'csv' });
Both fields are required in this form. An alias with only a target is the plain string form
written the long way, so Glotto rejects it rather than quietly treating it as one.
Limitations
- Deprecating a model, field, or individual enum member is not supported yet;
deprecatedis keyed by operation.
See also
glotto.ymlreference — the full config surface.- Drift detection — the gate that keeps committed output honest.
- The verification report — what every regeneration proves.