Motivation / Current State
@@override is the only tool available when the change touches an operation's parameter list, and it is an all-or-nothing replacement:
- Full clones for tiny changes. To change one parameter we must copy the operation's complete signature. The single intended edit is buried in a large duplicate.
- Risk of definition drift. The override is a static snapshot. When the base operation changes (new parameter, new response header, route change, new API version), the override silently goes stale and must be kept in sync by hand. Nothing enforces parity.
- Repeated across many operations. In a single service
client.tsp this pattern recurs for numerous operations, each a large clone that exists to change one small thing.
- Duplicated suppressions. Any suppressions applied to the definition in
routes.tsp must be restated here.
Concrete example
In the Storage Blob client.tsp, making the metadata header required for Rust on container setMetadata requires a full operation redefinition.
alias MetadataHeadersRequired = {
/** The metadata headers. */
@alternateType(Record<string>, "rust")
@header("x-ms-meta")
metadata: string; // <-- the ONLY intended change vs. the base op, now required dropping the '?'
};
#suppress "@azure-tools/typespec-azure-core/use-standard-operations" "Existing API"
#suppress "@azure-tools/typespec-azure-core/no-response-body" "Existing API"
#suppress "@azure-tools/typespec-azure-core/use-standard-names" "Existing API"
@put
@sharedRoute
@route("?restype=container&comp=metadata")
op setMetadataRequiredMetadataContainer is StorageOperationNoBody<
{
...TimeoutParameter;
...LeaseIdOptionalParameter;
...MetadataHeadersRequired;
...IfModifiedSinceParameter;
},
{
...EtagResponseHeaderPrivate;
...LastModifiedResponseHeaderPrivate;
}
>;
@@override(Container.setMetadata, setMetadataRequiredMetadataContainer, "rust");
This is not a one-off
The same shape repeats throughout this single file: each a full operation clone whose only real purpose is a one-parameter delta:
setMetadataRequiredMetadataContainer (container setMetadata, Rust): making the metadata header required instead of optional (metadata? → metadata).
setMetadataRequiredMetadataBlob (blob setMetadata, Rust): same as above
setAccessPolicyRequiredContainerAcl (container setAccessPolicy, Rust): containerAcl request body required instead of optional.
appendBlockNoStructuredMessage (append appendBlock, Rust): omitting the structured-message parameters (not yet implemented) from the request.
stageBlockNoStructuredMessage (block stageBlock, Rust): same as above
uploadPagesNoStructuredMessage (page uploadPages, Rust): same as above
Why every one of these requires a full clone today
All six deltas are parameter-level edits- flip one parameter's optionality or drop a couple of parameters from the request. None of them touch the route, the response shape, or the rest of the parameter list. Yet each currently require a full redefinition of 99% the same functionality but augmenting a handful of parameters. This also, as mentioned above, become a maintenance nightmare given that these are handwritten and must be maintained alongside the actual routes.tsp definition.
Motivation / Current State
@@overrideis the only tool available when the change touches an operation's parameter list, and it is an all-or-nothing replacement:client.tspthis pattern recurs for numerous operations, each a large clone that exists to change one small thing.routes.tspmust be restated here.Concrete example
In the Storage Blob
client.tsp, making themetadataheader required for Rust on containersetMetadatarequires a full operation redefinition.This is not a one-off
The same shape repeats throughout this single file: each a full operation clone whose only real purpose is a one-parameter delta:
setMetadataRequiredMetadataContainer(containersetMetadata, Rust): making themetadataheader required instead of optional (metadata?→metadata).setMetadataRequiredMetadataBlob(blobsetMetadata, Rust): same as abovesetAccessPolicyRequiredContainerAcl(containersetAccessPolicy, Rust):containerAclrequest body required instead of optional.appendBlockNoStructuredMessage(appendappendBlock, Rust): omitting the structured-message parameters (not yet implemented) from the request.stageBlockNoStructuredMessage(blockstageBlock, Rust): same as aboveuploadPagesNoStructuredMessage(pageuploadPages, Rust): same as aboveWhy every one of these requires a full clone today
All six deltas are parameter-level edits- flip one parameter's optionality or drop a couple of parameters from the request. None of them touch the route, the response shape, or the rest of the parameter list. Yet each currently require a full redefinition of 99% the same functionality but augmenting a handful of parameters. This also, as mentioned above, become a maintenance nightmare given that these are handwritten and must be maintained alongside the actual
routes.tspdefinition.