New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Streaming HTTP POST API for the System.Net.Http.Json extensions #101564
Comments
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis |
There's no precedent in us using two generic parameters for the request and response types, the existing POST methods simply return an If I'm honest, I think the existing RequestModel model = ...;
HttpResponseMessage response = await client.PostAsJsonAsync("/openai/chat", model);
await foreach (ResponseModel item in response.ReadFromJsonAsAsyncEnumerable<ResponseModel>())
{
...
} |
On the other hand, that sample demonstrates how easy it is to use it wrong. This would preserve the goal of streaming the response, but also with the difference that you now don't enforce the timeout/response size limits. var request = new HttpRequestMessage(HttpMethod.Post, "/openai/chat")
{
Content = JsonContent.Create(model)
};
using HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
await foreach (ResponseModel item in response.ReadFromJsonAsAsyncEnumerable<ResponseModel>())
{
...
} cc: @dotnet/ncl |
Does this help? It's my shot at it, and it appears to not buffer and stream. public static async IAsyncEnumerable<TResponse> PostFromJsonAsAsyncEnumerable<TRequest, TResponse>(
this HttpClient client,
string requestUri,
TRequest request,
[EnumeratorCancellation] CancellationToken cancellationToken = default)
{
var requestMessage = new HttpRequestMessage(HttpMethod.Post, requestUri);
using var ms = new MemoryStream();
await JsonSerializer.SerializeAsync(ms, request, JsonSerializerSettings.Options, cancellationToken: cancellationToken);
ms.Position = 0;
using var requestContent = new StreamContent(ms);
requestMessage.Content = requestContent;
requestContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
requestMessage.Headers.Add("Accept", "application/json");
using var response = await client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
response.EnsureSuccessStatusCode();
var items = response.Content.ReadFromJsonAsAsyncEnumerable<TResponse>(cancellationToken);
await foreach (var item in items)
{
if (cancellationToken.IsCancellationRequested)
throw new TaskCanceledException();
if (item is null)
continue;
yield return item;
}
} |
Perhaps then the answer is to expose overloads to the existing |
Background and motivation
As a follow up to the related API proposal #87577, this aims to include
Post*
APIs to theHttpClientJsonExtensions
class as extensions methods.API Proposal
API Usage
Alternative Designs
No response
Risks
No response
The text was updated successfully, but these errors were encountered: