Amazon.Lambda.AspNetCoreServer 9.0.1
Amazon.Lambda.AspNetCoreServer
This package makes it easy to run ASP.NET Core Web API applications as a Lambda function with API Gateway or an ELB Application Load Balancer. This allows .NET Core developers to create "serverless" applications using the ASP.NET Core Web API framework.
The function takes a request from an API Gateway Proxy or from an Application Load Balancer and converts that request into the classes the ASP.NET Core framework expects and then converts the response from the ASP.NET Core framework into the response body that API Gateway Proxy or Application Load Balancer understands.
Supported .NET versions
This library supports .NET 6 and above. Lambda provides managed runtimes for long term supported (LTS) versions like .NET 6 and .NET 8. To use standard term supported (STS) versions like .NET 9 the Lambda function must be bundled as a self contained executable or an OCI image.
Amazon.Lambda.AspNetCoreServer vs Amazon.Lambda.AspNetCoreServer.Hosting
The Amazon.Lambda.AspNetCoreServer
is typically used with the older ASP.NET Core pattern of having a Startup
class to setup the ASP.NET Core application. This allows you to share the ASP.NET Core setup logic between the LambdaEntryPoint
and the normal Main
entrypoint used for running the ASP.NET Core applications locally. For integrating Lambda into an ASP.NET Core project using the minimal api pattern checkout the Amazon.Lambda.AspNetCoreServer.Hosting. This package integrates Amazon.Lambda.AspNetCoreServer setup into the project's Main
or top level statements.
Using Amazon.Lambda.AspNetCoreServer directly instead of Amazon.Lambda.AspNetCoreServer.Hosting is recommened when projects need to customize the Lambda behavior through the LambdaEntryPoint
by overriding the base class methods.
Lambda Entry Point
In the ASP.NET Core application add a class that will be the entry point for Lambda to call into the application. Commonly this class
is called LambdaEntryPoint
. The base class is determined based on where the Lambda functions will be invoked from.
Lambda Involve | Base Class |
---|---|
API Gateway REST API | APIGatewayProxyFunction |
API Gateway WebSocket API | APIGatewayProxyFunction |
API Gateway HTTP API Payload 1.0 | APIGatewayProxyFunction |
API Gateway HTTP API Payload 2.0 | APIGatewayHttpApiV2ProxyFunction |
Application Load Balancer | ApplicationLoadBalancerFunction |
Note: HTTP API default to payload 2.0 so unless 1.0 is explicitly set the base class should be APIGatewayHttpApiV2ProxyFunction.
The function handler for the Lambda function will be TestWebAppTestWebApp.LambdaEntryPointFunctionHandlerAsync.
ASP.NET Core setup
The LambdaEntryPoint
class in the ASP.NET Core project inherits Init
methods that can be used to setup ASP.NET Core application. The most common approach is override the Init
and using the UseStartup
method on the IWebHostBuilder
register the startup class. The startup class contains ASP.NET Core setup logic that can be shared between the LambdaEntryPoint
and the project's Main
method.
Example LambdaEntryPoint
:
public class LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
{
/// <summary>
/// The builder has configuration, logging and Amazon API Gateway already configured. The startup class
/// needs to be configured in this method using the UseStartup<>() method.
/// </summary>
/// <param name="builder">The IWebHostBuilder to configure.</param>
protected override void Init(IWebHostBuilder builder)
{
builder
.UseStartup<Startup>();
}
}
Example Startup
:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Welcome to running ASP.NET Core on AWS Lambda");
});
});
}
}
JSON Serialization
Starting with version 5.0.0 when targeting .NET Core 3.1 Amazon.Lambda.Serialization.SystemTextJson
. When targeting previous
versions of .NET Core or using a version of Amazon.Lambda.AspNetCoreServer before 5.0.0 will use Amazon.Lambda.Serialization.Json
.
Web App Path Base
By default this package configure the path base for incoming requests to be root of the API Gateway Stage or Application Load Balancer.
If you want to treat a subresource in the resource path to be the path base you will need to modify how requests are marshalled
into ASP.NET Core. For example if the listener of an Application Load Balancer
points to a Lambda Target Group for requests starting with /webapp/*
and you want to call a controller api/values
ASP.NET Core
will think the resource you want to access is /webapp/api/values
which will return a 404 NotFound.
In the LambdaEntryPoint
class you can override the PostMarshallRequestFeature
method to add custom logic to how
the path base is computed. In the example below it configures the path base to be /webapp/
. When the Application Load balancer
sends in a request with the resource path set to /webapp/api/values. This code configures the ASP.NET Core request to have the
path base set to /webapp/ and the path to /api/values.
public class LambdaEntryPoint : ApplicationLoadBalancerFunction
{
protected override void Init(IWebHostBuilder builder)
{
builder
.UseStartup<Startup>();
}
protected override void PostMarshallRequestFeature(IHttpRequestFeature aspNetCoreRequestFeature, ApplicationLoadBalancerRequest lambdaRequest, ILambdaContext lambdaContext)
{
aspNetCoreRequestFeature.PathBase = "/webapp/";
// The minus one is ensure path is always at least set to `/`
aspNetCoreRequestFeature.Path =
aspNetCoreRequestFeature.Path.Substring(aspNetCoreRequestFeature.PathBase.Length - 1);
lambdaContext.Logger.LogLine($"Path: {aspNetCoreRequestFeature.Path}, PathBase: {aspNetCoreRequestFeature.PathBase}");
}
}
Supporting Binary Response Content
The interface between the API Gateway/Application Load Balancer and Lambda assumes response content to be returned as a UTF-8 string. In order to return binary content it is necessary to encode the raw response content in Base64 and to set a flag in the response object that Base64-encoding has been applied.
In order to facilitate this mechanism, the base class maintains a registry of MIME content types and how they should be transformed before being returned to the calling API Gateway or Application Load Balancer. For any binary content types that are returned by your application, you should register them for Base64 tranformation and then the framework will take care of intercepting any such responses and making an necessary transformations to preserve the binary content. For example:
using System.IO;
using Amazon.Lambda.AspNetCoreServer;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
namespace TestWebApp
{
public class LambdaFunction : APIGatewayProxyFunction
{
protected override void Init(IWebHostBuilder builder)
{
// Register any MIME content types you want treated as binary
RegisterResponseContentEncodingForContentType("application/octet-stream",
ResponseContentEncoding.Base64);
// ...
}
}
// In your controller actions, be sure to provide a Content Type for your responses
public class LambdaController : Controller
{
public IActionResult GetBinary()
{
var binData = new byte[] { 0x00, 0x01, 0x02, 0x03 };
return base.File(binData, "application/octet-stream");
}
}
}
IMPORTANT - Registering Binary Response with API Gateway
In order to use this mechanism to return binary response content, in addition to registering any binary MIME content types that will be returned by your application, it also necessary to register those same content types with the API Gateway using either the console or the REST interface.
For Application Load Balancer this step is not necessary.
Default Registered Content Types
By default several commonly used MIME types that are typically used with Web API services are already pre-registered. You can make use of these content types without any further changes in your code, however, for any binary content types, you do still need to make the necessary adjustments in the API Gateway as described above.
MIME Content Type | Response Content Encoding |
---|---|
text/plain |
Default (UTF-8) |
text/xml |
Default (UTF-8) |
application/xml |
Default (UTF-8) |
application/json |
Default (UTF-8) |
text/html |
Default (UTF-8) |
text/css |
Default (UTF-8) |
text/javascript |
Default (UTF-8) |
text/ecmascript |
Default (UTF-8) |
text/markdown |
Default (UTF-8) |
text/csv |
Default (UTF-8) |
application/octet-stream |
Base64 |
image/png |
Base64 |
image/gif |
Base64 |
image/jpeg |
Base64 |
application/zip |
Base64 |
application/pdf |
Base64 |
No packages depend on Amazon.Lambda.AspNetCoreServer.
.NET 6.0
- Amazon.Lambda.APIGatewayEvents (>= 2.7.1)
- Amazon.Lambda.ApplicationLoadBalancerEvents (>= 2.2.0)
- Amazon.Lambda.Core (>= 2.3.0)
- Amazon.Lambda.Logging.AspNetCore (>= 3.1.0)
- Amazon.Lambda.Serialization.SystemTextJson (>= 2.4.3)
.NET 8.0
- Amazon.Lambda.APIGatewayEvents (>= 2.7.1)
- Amazon.Lambda.ApplicationLoadBalancerEvents (>= 2.2.0)
- Amazon.Lambda.Core (>= 2.3.0)
- Amazon.Lambda.Logging.AspNetCore (>= 3.1.0)
- Amazon.Lambda.Serialization.SystemTextJson (>= 2.4.3)
Version | Downloads | Last updated |
---|---|---|
9.0.3 | 0 | 11/26/2024 |
9.0.2 | 0 | 11/20/2024 |
9.0.1 | 5 | 09/21/2024 |
9.0.0 | 16 | 02/17/2024 |
8.1.1 | 6 | 12/09/2023 |
8.1.0 | 8 | 08/26/2023 |
8.0.0 | 8 | 08/31/2023 |
7.3.0 | 4 | 08/31/2023 |
7.2.0 | 6 | 07/07/2022 |
7.1.0 | 9 | 08/28/2023 |
7.0.1 | 8 | 08/31/2023 |
7.0.0 | 10 | 08/31/2023 |
6.1.0 | 8 | 08/26/2023 |
6.0.3 | 6 | 08/31/2023 |
6.0.2 | 8 | 08/29/2023 |
6.0.1 | 7 | 12/08/2023 |
6.0.0 | 9 | 08/25/2023 |
5.3.1 | 8 | 08/29/2023 |
5.3.0 | 6 | 12/08/2023 |
5.2.0 | 6 | 08/27/2023 |
5.1.6 | 8 | 08/26/2023 |
5.1.5 | 7 | 08/25/2023 |
5.1.4 | 7 | 08/28/2023 |
5.1.3 | 6 | 08/31/2023 |
5.1.2 | 9 | 08/29/2023 |
5.1.1 | 9 | 12/30/2020 |
5.1.0 | 9 | 08/25/2023 |
5.0.0 | 10 | 08/31/2023 |
4.1.0 | 10 | 08/28/2023 |
4.0.0 | 7 | 08/31/2023 |
3.1.0 | 8 | 08/27/2023 |
3.0.4 | 9 | 08/29/2023 |
3.0.3 | 6 | 08/25/2023 |
3.0.2 | 7 | 12/08/2023 |
3.0.1 | 6 | 08/28/2023 |
3.0.0 | 8 | 08/29/2023 |
2.1.0 | 10 | 08/26/2023 |
2.0.4 | 10 | 08/24/2023 |
2.0.3 | 6 | 12/08/2023 |
2.0.2 | 8 | 08/27/2023 |
2.0.1 | 10 | 08/28/2023 |
2.0.0 | 7 | 08/28/2023 |
0.10.2-preview1 | 5 | 08/29/2023 |
0.10.1-preview1 | 8 | 08/28/2023 |
0.10.0-preview1 | 6 | 08/30/2023 |
0.9.0-preview1 | 6 | 06/13/2023 |
0.8.6-preview1 | 7 | 06/13/2023 |
0.8.5-preview1 | 6 | 12/08/2023 |
0.8.4-preview1 | 9 | 06/14/2023 |
0.8.3-preview1 | 8 | 06/12/2023 |
0.8.2-preview1 | 8 | 06/13/2023 |
0.8.1-preview1 | 6 | 06/14/2023 |
0.8.0-preview1 | 7 | 06/12/2023 |