goofballLogic
goofballLogic

Reputation: 40459

How to return stream of data from Azure Function (HTTP)

I need to make a series of database calls from an Azure function and return results (chunks of text) to the http caller as they become available. This could be sporadically over the course of a minute or so.

I don't want a "file download" response just the data sent over the response stream.

Is there a way to write to the response body stream in an Azure function?

Edit:

Attempts to create my own IActionResult hit problems when writing to the response body stream Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.

Upvotes: 3

Views: 8344

Answers (1)

Andy
Andy

Reputation: 13517

Here is an example of an HttpTrigger Azure Function:

[FunctionName("Function1")]
public async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
    ILogger log)
{
    return new OkResult();
}

You can get to the response object by using the HttpRequest req parameter:

var response = req.HttpContext.Response;

We can drop the return type and simply return Task, then stream data as so:

public class Function1
{
    private async IAsyncEnumerable<string> GetDataAsync()
    {
        for (var i = 0; i < 100; ++i)
        {
            yield return "{\"hello\":\"world\"}";
        }
    }

    [FunctionName("Function1")]
    public async Task Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        var response = req.HttpContext.Response;

        response.StatusCode = 200;
        response.ContentType = "application/json-data-stream";

        await using var sw = new StreamWriter(response.Body);
        await foreach (var msg in GetDataAsync())
        {
            await sw.WriteLineAsync(msg);
        }

        await sw.FlushAsync();
    }
}

Upvotes: 8

Related Questions