diff --git a/.github/workflows/source-generator-ci.yml b/.github/workflows/source-generator-ci.yml deleted file mode 100644 index e1fe6bc2d..000000000 --- a/.github/workflows/source-generator-ci.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: Lambda Annotations CI - -on: - workflow_dispatch: - push: - branches: - - dev - pull_request: - -jobs: - lambda-annotations-build-pack-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Setup .NET 3.1 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 3.1.x - - name: Setup .NET 6.0 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 6.0.x - - name: Setup .NET 8.0 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.0.x - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@8c3f20df09ac63af7b3ae3d7c91f105f857d8497 #v4 - with: - aws-access-key-id: ${{ secrets.CI_AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.CI_AWS_ACCESS_KEY_SECRET }} - aws-region: us-west-2 - role-to-assume: ${{ secrets.CI_TEST_RUNNER_ROLE }} - role-duration-seconds: 3600 - role-session-name: test-runner - role-skip-session-tagging: true - - name: Restore dependencies - run: | - dotnet restore Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj - dotnet restore Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj - dotnet restore Libraries/test/TestServerlessApp.IntegrationTests/TestServerlessApp.IntegrationTests.csproj - - name: Build - run: | - dotnet build Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj --no-restore --configuration Release - dotnet build Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj --no-restore --configuration Release - dotnet build Libraries/test/TestServerlessApp.IntegrationTests/TestServerlessApp.IntegrationTests.csproj --no-restore --configuration Release - - name: Pack - run: dotnet pack Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj -p:NuspecFile=../Amazon.Lambda.Annotations.nuspec --no-build --configuration Release --output "PackResults" - - name: Upload pack results - uses: actions/upload-artifact@v4 - with: - name: lambda-annotations-nuget-package - path: PackResults - # Use always() to always run this step to publish test results when there are test failures - if: ${{ always() }} - - name: Test - run: | - dotnet test Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj --no-build --configuration Release --verbosity normal --logger trx --results-directory "TestResults" - dotnet test Libraries/test/TestServerlessApp.IntegrationTests/TestServerlessApp.IntegrationTests.csproj --no-build --configuration Release --verbosity normal --logger trx --results-directory "TestResults" - - name: Upload test results - uses: actions/upload-artifact@v4 - with: - name: lambda-annotations-test-result - path: TestResults - # Use always() to always run this step to publish test results when there are test failures - if: ${{ always() }} - - test-app-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Setup .NET 6.0 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 6.0.x - - name: Setup .NET 8.0 - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.0.x - - name: Restore dependencies - run: dotnet restore Libraries/test/TestServerlessApp/TestServerlessApp.csproj - - name: Build - run: dotnet build Libraries/test/TestServerlessApp/TestServerlessApp.csproj --no-restore --configuration Release --verbosity detailed - - name: Upload built assemblies - uses: actions/upload-artifact@v4 - with: - name: test-app-build-result - path: Libraries/test/TestServerlessApp/bin/Release/net6.0 diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/README.md b/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/README.md index c8d9efa10..bf3455a65 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/README.md +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer.Hosting/README.md @@ -9,6 +9,11 @@ This package allows ASP .NET Core applications written using the minimal api sty The `AddAWSLambdaHosting` will setup the `Amazon.Lambda.AspNetCoreServer` package to process the incoming Lambda events as ASP .NET Core requests. It will also initialize `Amazon.Lambda.RuntimeSupport` package to interact with the Lambda service. +## 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. + ## Sample ASP .NET Core application The code sample below is the typical initilization code for an ASP .NET Core application using the minimal api style. The one difference is the extra line of code calling `AddAWSLambdaHosting`. diff --git a/Libraries/src/Amazon.Lambda.AspNetCoreServer/README.md b/Libraries/src/Amazon.Lambda.AspNetCoreServer/README.md index c223c251a..42e9ba000 100644 --- a/Libraries/src/Amazon.Lambda.AspNetCoreServer/README.md +++ b/Libraries/src/Amazon.Lambda.AspNetCoreServer/README.md @@ -8,6 +8,17 @@ or from an [Application Load Balancer](https://docs.aws.amazon.com/elasticloadba 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](https://github.com/aws/aws-lambda-dotnet/tree/master/Libraries/src/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 @@ -23,95 +34,71 @@ is called `LambdaEntryPoint`. The base class is determined based on where the La **Note:** HTTP API default to payload 2.0 so unless 1.0 is explicitly set the base class should be APIGatewayHttpApiV2ProxyFunction. -Here is an example implementation of the Lamba function in an ASP.NET Core Web API application. -```csharp -using System.IO; +The function handler for the Lambda function will be **TestWebApp::TestWebApp.LambdaEntryPoint::FunctionHandlerAsync**. -using Amazon.Lambda.AspNetCoreServer; -using Microsoft.AspNetCore.Hosting; +## ASP.NET Core setup -namespace TestWebApp +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`: +```csharp +public class LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction { /// - /// This class extends from APIGatewayProxyFunction which contains the method FunctionHandlerAsync which is the - /// actual Lambda function entry point. The Lambda handler field should be set to - /// - /// AWSServerless19::AWSServerless19.LambdaEntryPoint::FunctionHandlerAsync + /// 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. /// - public class LambdaEntryPoint : - - // The base class must be set to match the AWS service invoking the Lambda function. If not Amazon.Lambda.AspNetCoreServer - // will fail to convert the incoming request correctly into a valid ASP.NET Core request. - // - // API Gateway REST API -> Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction - // API Gateway HTTP API payload version 1.0 -> Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction - // API Gateway HTTP API payload version 2.0 -> Amazon.Lambda.AspNetCoreServer.APIGatewayHttpApiV2ProxyFunction - // Application Load Balancer -> Amazon.Lambda.AspNetCoreServer.ApplicationLoadBalancerFunction - // - // Note: When using the AWS::Serverless::Function resource with an event type of "HttpApi" then payload version 2.0 - // will be the default and you must make Amazon.Lambda.AspNetCoreServer.APIGatewayHttpApiV2ProxyFunction the base class. - - Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction + /// The IWebHostBuilder to configure. + protected override void Init(IWebHostBuilder builder) { - /// - /// 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. - /// - /// - protected override void Init(IWebHostBuilder builder) - { - builder - .UseStartup(); - } + builder + .UseStartup(); } } ``` -The function handler for the Lambda function will be **TestWebApp::TestWebApp.LambdaEntryPoint::FunctionHandlerAsync**. - -## Bootstrapping application (IWebHostBuilder vs IHostBuilder) - -ASP.NET Core applications are bootstrapped by using a host builder. The host builder is used to configure all of the required services needed to run the ASP.NET Core application. With Amazon.Lambda.AspNetCoreServer there are multiple options for customizing the bootstrapping and they vary between targeted versions of .NET Core. - -### ASP.NET Core 3.1 - -ASP.NET Core 3.1 uses the generic `IHostBuilder` to bootstrap the application. In a typical ASP.NET Core 3.1 application the `Program.cs` file will bootstrap the application using `IHostBuilder` like the following snippet shows. As part of creating the `IHostBuilder` an `IWebHostBuilder` is created by the `ConfigureWebHostDefaults` method. - +Example `Startup`: ```csharp -public static IHostBuilder CreateHostBuilder(string[] args) => - Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); -``` - -Amazon.Lambda.AspNetCoreServer creates this `IHostBuilder` and configures all of the default settings needed to run the ASP.NET Core application in Lambda. - -There are two `Init` methods that can be overridden to customize the `IHostBuilder`. The most common customization is to override the `Init(IWebHostBuilder)` method and set the startup class via the `UseStartup` method. To customize the `IHostBuilder` then override the `Init(IHostBuilder)`. **Do not call `ConfigureWebHostDefaults` when overriding `Init(IHostBuilder)` because Amazon.Lambda.AspNetCoreServer will call `ConfigureWebHostDefaults` when creating the `IHostBuilder`. By calling `ConfigureWebHostDefaults` in the `Init(IHostBuilder)` method, the `IWebHostBuilder` will be configured twice.** - -If you want complete control over creating the `IHostBuilder` then override the `CreateHostBuilder` method. When overriding the `CreateHostBuilder` method neither of the `Init` methods will be called unless the override calls the base implementation. When overriding `CreateHostBuilder` it is recommended to call `ConfigureWebHostLambdaDefaults` instead of `ConfigureWebHostDefaults` to configure the `IWebHostBuilder` for Lambda. - -If the `CreateWebHostBuilder` is overridden in an ASP.NET Core 3.1 application then only the `IWebHostBuilder` is used for bootstrapping using the same pattern that ASP.NET Core 2.1 applications use. `CreateHostBuilder` and `Init(IHostBuilder)` will not be called when `CreateWebHostBuilder` is overridden. - - - -### ASP.NET Core 2.1 +public class Startup +{ + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } -ASP.NET Core 2.1 applications are bootstrapped with the `IWebHostBuilder` type. Amazon.Lambda.AspNetCoreServer will create an instance of `IWebHostBuilder` and it can be customized by overriding the `Init(IWebHostBuilder)` method. The most common customization is configuring the startup class via the `UseStartup` method. + public IConfiguration Configuration { get; } -If you want complete control over creating the `IWebHostBuilder` then override the `CreateWebHostBuilder` method. When overriding the `CreateWebHostBuilder` method the `Init(IWebHostBuilder)` method will not be called unless the override calls the base implementation or explicitly calls the `Init(IWebHostBuilder)` method. + // 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(); + } -## Access to Lambda Objects from HttpContext + app.UseHttpsRedirection(); -The original lambda request object and the `ILambdaContext` object can be accessed from the `HttpContext.Items` collection. + app.UseRouting(); -| Constant | Object | -|-------|--------| -| AbstractAspNetCoreFunction.LAMBDA_CONTEXT | ILambdaContext | -| AbstractAspNetCoreFunction.LAMBDA_REQUEST_OBJECT |
  • APIGatewayProxyFunction -> APIGatewayProxyRequest
  • APIGatewayHttpApiV2ProxyFunction -> APIGatewayHttpApiV2ProxyRequest
  • ApplicationLoadBalancerFunction -> ApplicationLoadBalancerRequest
| + 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 diff --git a/README.md b/README.md index 36d1ed583..f5ce22798 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# AWS Lambda for .NET [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-lambda-dotnet?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +# AWS Lambda for .NET Repository for the AWS NuGet packages and Blueprints to support writing AWS Lambda functions using .NET Core.