microsoft / microsoft/typespec

[http-client-csharp] Support optional success response bodies

Open
#11,651 2 comments 1 reaction 0 assignees View on GitHub
emitter:client:csharp feature
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.