feat: add wrap-non-model-return option to prevent breaking changes for non-model types#3805
feat: add wrap-non-model-return option to prevent breaking changes for non-model types#3805
wrap-non-model-return option to prevent breaking changes for non-model types#3805Conversation
…ring TSP migration Co-authored-by: MaryGao <9943211+MaryGao@users.noreply.github.com>
…ments Co-authored-by: MaryGao <9943211+MaryGao@users.noreply.github.com>
wrap-non-model-return option to prevent breaking changes during TSP migration
|
@copilot two issues found in our CI
|
…or wrap-non-model-return Co-authored-by: MaryGao <9943211+MaryGao@users.noreply.github.com>
Fixed in commit 6c87836.
|
|
@copilot please genereate XXXResponse model in |
Co-authored-by: MaryGao <9943211+MaryGao@users.noreply.github.com>
Done in commit 67f6a44. Added |
|
@copilot two issues found
|
Co-authored-by: MaryGao <9943211+MaryGao@users.noreply.github.com>
|
@copilot the pr should be ready for review and pls update the pr description accordingly. |
Fixed in commit bb3be37. The root cause was that commit 6738777 mistakenly called The fix uses
|
bb3be37 to
6738777
Compare
|
…e tests and modular UT Co-authored-by: v-jiaodi <80496810+v-jiaodi@users.noreply.github.com>
…t any types Co-authored-by: v-jiaodi <80496810+v-jiaodi@users.noreply.github.com>
Fixed in commits 3977f63 and 9764598.
|
packages/typespec-test/test/batch_modular/generated/typespec-ts/src/models/models.ts
Show resolved
Hide resolved
| } | ||
|
|
||
| export async function _getTaskFileDeserialize(result: PathUncheckedResponse): Promise<Uint8Array> { | ||
| const expectedStatuses = ["200"]; |
There was a problem hiding this comment.
Does this mean that an error will not be returned if there is any? I see that the status is stored in the HttpBrowserStreamResponse or HttpNodeStreamResponse from the asBrowserStream or asNodeStream methods, along with the headers and request. Should we return all of these, similar to how the getBinaryResponse helper works?
There was a problem hiding this comment.
An error body will also be returned since now customers use the streaming way to handle responses. I don't think we will return them all: https://github.com/Azure/autorest.typescript/pull/3805/changes#diff-645b7a8aa61f119778507670f7a76b30227f006ff3640d714d5b8814f6f7f298R417-R420, similar to getBinaryResponse only response body will take into consideration.
That's why our integration case as below
There was a problem hiding this comment.
Do you mean returning only the error body is enough for customers? In addition, getBinaryResponse preserves the status:
…nto copilot/fix-tsp-migration-issues
PR Summary
This PR adds a new emitter option,
wrap-non-model-return, to prevent breaking changes when migrating TypeSpec clients that return non-model response body types. For Azure services, by default we would expose the wrapper return to mitigate the breakings.Why
During TSP migration, operations returning non-model payloads (especially scalars, arrays, and binary payloads) could produce shape differences that broke downstream consumers. This change aligns return-shape behavior and provides explicit control via configuration.
What changed
wrapNonModelReturnto RLC options inpackages/rlc-common/src/interfaces.ts.wrap-non-model-returnemitter option inpackages/typespec-ts/src/lib.ts.true) inpackages/typespec-ts/src/transform/transfromRLCOptions.ts.{ body: T }{ blobBody?, readableStreamBody? }packages/typespec-ts/src/modular/helpers/operationHelpers.tsemitNonModelResponseTypes()to generate and exposeXxxResponsealiases in models:packages/typespec-ts/src/modular/emit/emitModels.tsmodels/models.tsand publicly re-exportedFixes during PR iteration
getBinaryResponseas helper function, notStreamableMethodmethod).Validation
All specs succeeded!reported in thread).545 passingreported in thread).Impact
XxxResponsealiases discoverable and publicly consumable frommodels.Linked issue
#3655([migration tsp] A non-model response body type will introduce breakings during tsp migration)Original prompt
This section details on the original issue you should resolve
<issue_title>[migration tsp] A non-model response body type will introduce breakings during tsp migration</issue_title>
<issue_description>1: This breaking is found in verify breakings in tsp conversion.
Breaking message:
Details:
The service has an operation named
listVerifiedExchangeOnlineDomainsand its response is a string array:Swagger:
In HLC, we will separately package the response into a model called xxxResponse, and based on this code, and assign a body property to a non-model response:
However, in Modular, the
string[]type will be used as the promise response type directly.TypeSpec:
Modular:
2: The same breakings are introduced for file/bytes type.
Related issue: #3635 (Modular fails to generate if the response type is
File<"application/octet-stream">).Original Swagger:
HLC:
blobBodyandreadableStreamBodyare also generated from codegen, not source Swagger.In modular, it will be
Do we accept this break or need to make the behavior the same as HLC?
I create a pr to investigate this
Proposal
We decided not accepting this breaking from HLC and Modular so we decide to have a feature flag named
wrap-non-model-returnin Modular and by default enabling this flag for all services, when the flag is set as false, we will still generate the old modular ways.For normal operation(non paging or LRO operations), when the return type is non-model type, HLC would genereate a wrapper interface XXXResponse not directly returning the model type, so to not introduce any breakings in Modular, we would generate the same interfaces in these cases.
The XXXResponse would be like
OperationGroupNameMethodNameResponse.Case 1: If the return type is bytes type &the mediaType is KnownMediaType.Binary
Here is the code to define the binary type. Practical examples that map to binary in the content-type classifier are:application/octet-stream, image/*, audio...
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.