aws / aws-lambda-dotnet

Libraries, samples and tools to help .NET Core developers develop AWS Lambda functions.
Apache License 2.0
1.55k stars 477 forks source link

Add response streaming support #1635

Open plaisted opened 7 months ago

plaisted commented 7 months ago

Describe the feature

Add support for using lambda response streaming when returning streams in a dotnet lambda function.

https://aws.amazon.com/blogs/compute/introducing-aws-lambda-response-streaming/

Use Case

I would like to stream large S3 objects to http clients using a lambda URL.

Proposed Solution

Add functionality to enable returned streams to be sent using application/vnd.awslambda.http-integration-response content type and prefixed with required JSON prelude / null bytes. Allow status code / http headers to be configured and added to JSON prelude.

Other Information

No response

Acknowledgements

AWS .NET SDK and/or Package version used

Amazon.Lambda.RuntimeSupport 1.10.0

Targeted .NET Platform

.net 8

Operating System and version

debian container in lambda

ashishdhingra commented 7 months ago

Discussion https://github.com/aws/aws-lambda-dotnet/discussions/1632 opened few days ago.

plaisted commented 7 months ago

I was able to get this working with pretty minimal changes. I'll push it somewhere in case anyone wants to replicate until it's officially supported.

plaisted commented 7 months ago

Certainly not hardened but is working for my use case of returning dynamic http content from a lambda URL: https://github.com/plaisted/aws-lambda-dotnet/commit/3d45f5a3db8e98030b502ca9574b6cf36ff2c5cc

Usable by returning new StreamedResponse class which is a basic wrapper of a normal .net stream + http info:

    [LambdaFunction]
    public async Task<StreamedResponse> CustomerCDN(APIGatewayHttpApiV2ProxyRequest req, ILambdaContext ctx)
    {
        // dummy content
        await Task.Yield();
        var content = new MemoryStream(Encoding.UTF8.GetBytes("Example content!!".ToString()));

        // return using lambda response streaming
        return new StreamedResponse(content)
        {
            Headers = new Dictionary<string, string>
            {
                ["Content-Type"] = "text/plain; charset=utf-8",
                ["Cache-Control"] = "no-store, private, stale-if-error=0"
            }
        };
    }
paolofulgoni commented 3 months ago

Another use case would be streaming an LLM response (e.g. with Anthropic Claude)

normj commented 3 months ago

@paolofulgoni Good use case. Definitely feature I want to get to.