microsoft / microsoft/typespec
[http-client-csharp] Support optional success response bodies
- Dominant language
- Java
- Stars
- 5.9k
- Forks
- 394
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 104
Description
## Description
The C# emitter should eventually support operations that have multiple successful responses where one response contains a body and another contains no body.
```tsp
op getLayout(): {
@statusCode statusCode: 200;
@body layout: BlobLayout;
} | {
@statusCode statusCode: 204;
};
```
Both responses represent successful execution, but the convenience result value is optional. The emitter must not attempt to deserialize a body for the `204` response.
## Blocked on nullable reference support
Unbranded SCM support should be deferred until the C# emitter can preserve nullable reference annotations in generated client libraries. This is tracked by #7451 (with the broader nullable behavior discussion in #5811).
Without nullable annotations, the generated public signature is `ClientResult` even though `Value` may be null. That makes the optional contract invisible to callers and creates a foot gun. Once nullable annotations are supported, the intended shape is:
```csharp
ClientResult GetLayout(...)
```
using `ClientResult.FromOptionalValue(...)` and branching on declared no-body success status codes before deserialization.
Azure-specific emitters can independently use their established structural optional result shape, such as `NullableResponse`.
## Requirements after #7451
- Select the successful response that contains a body when determining the convenience value type, regardless of response ordering.
- Treat declared no-body success statuses as successful results without a value.
- Only branch by status when the no-body status is not also used by a body-bearing success response.
- Do not read or deserialize response content for no-body success statuses.
- Preserve access to the raw response, including status and headers.
- Cover synchronous and asynchronous convenience methods.
Related Spector scenario request: #11650
Contributor guide
Research direction
Start by reading #7451 and the nullable behavior discussion in #5811, then inspect the C# emitter's convenience methods and ClientResult.FromOptionalValue usage. Use the Spector scenario requested in #11650 as the behavioral reference. Done means synchronous and asynchronous methods preserve raw responses, avoid deserializing declared no-body success responses, and expose the optional value correctly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- api, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100