# ASP.NET Core Web API Serverless Application This project shows how to run an ASP.NET Core Web API project as an AWS Lambda exposed through Amazon API Gateway. The NuGet package [Amazon.Lambda.AspNetCoreServer](https://www.nuget.org/packages/Amazon.Lambda.AspNetCoreServer) contains a Lambda function that is used to translate requests from API Gateway into the ASP.NET Core framework and then the responses from ASP.NET Core back to API Gateway. ### Project Files ### * serverless.template - an AWS CloudFormation Serverless Application Model template file for declaring your Serverless functions and other AWS resources * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS * LambdaEntryPoint.fs - type that derives from **Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction**. The code in this file bootstraps the ASP.NET Core hosting framework. The Lambda function is defined in the base class. * LocalEntryPoint.fs - for local development this contains the executable Main function which bootstraps the ASP.NET Core hosting framework with Kestrel, as for typical ASP.NET Core applications. * Startup.fs - usual ASP.NET Core Startup type used to configure the services ASP.NET Core will use. * web.config - used for local development. * Controllers\ValuesController.fs - example Web API controller You may also have a test project depending on the options selected. ### Configuring for API Gateway HTTP API ### API Gateway supports the original REST API and the new HTTP API. In addition HTTP API supports 2 different payload formats. When using the 2.0 format the base type of `LambdaEntryPoint` must be `Amazon.Lambda.AspNetCoreServer.APIGatewayHttpApiV2ProxyFunction`. For the 1.0 payload format the base type is the same as REST API which is `Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction`. **Note:** when using the `AWS::Serverless::Function` CloudFormation resource with an event type of `HttpApi` the default payload format is 2.0 so the base type of `LambdaEntryPoint` must be `Amazon.Lambda.AspNetCoreServer.APIGatewayHttpApiV2ProxyFunction`. ### Configuring for Application Load Balancer ### To configure this project to handle requests from an Application Load Balancer instead of API Gateway change the base type of `LambdaEntryPoint` from `Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction` to `Amazon.Lambda.AspNetCoreServer.ApplicationLoadBalancerFunction`. ## Packaging as a Docker image. This project is configured to package the Lambda function as a Docker image. The default configuration for the project and the Dockerfile is to build the .NET project on the host machine and then execute the `docker build` command which copies the .NET build artifacts from the host machine into the Docker image. The `--docker-host-build-output-dir` switch, which is set in the `aws-lambda-tools-defaults.json`, triggers the AWS .NET Lambda tooling to build the .NET project into the directory indicated by `--docker-host-build-output-dir`. The Dockerfile has a **COPY** command which copies the value from the directory pointed to by `--docker-host-build-output-dir` to the `/var/task` directory inside of the image. Alternatively the Docker file could be written to use [multi-stage](https://docs.docker.com/develop/develop-images/multistage-build/) builds and have the .NET project built inside the container. Below is an example of building .NET 5 project inside the image. ```dockerfile FROM public.ecr.aws/lambda/dotnet:5.0 AS base FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim as build WORKDIR /src COPY ["BlueprintBaseName.1.csproj", "BlueprintBaseName.1/"] RUN dotnet restore "BlueprintBaseName.1/BlueprintBaseName.1.csproj" WORKDIR "/src/BlueprintBaseName.1" COPY . . RUN dotnet build "BlueprintBaseName.1.csproj" --configuration Release --output /app/build FROM build AS publish RUN dotnet publish "BlueprintBaseName.1.csproj" \ --configuration Release \ --runtime linux-x64 \ --self-contained false \ --output /app/publish \ -p:PublishReadyToRun=true FROM base AS final WORKDIR /var/task COPY --from=publish /app/publish . ``` ## Here are some steps to follow from Visual Studio: To deploy your Serverless application, right click the project in Solution Explorer and select *Publish to AWS Lambda*. To view your deployed application open the Stack View window by double-clicking the stack name shown beneath the AWS CloudFormation node in the AWS Explorer tree. The Stack View also displays the root URL to your published application. ## Here are some steps to follow to get started from the command line: Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. Install Amazon.Lambda.Tools Global Tools if not already installed. ``` dotnet tool install -g Amazon.Lambda.Tools ``` If already installed check if new version is available. ``` dotnet tool update -g Amazon.Lambda.Tools ``` Execute unit tests ``` cd "BlueprintBaseName.1/test/BlueprintBaseName.1.Tests" dotnet test ``` Deploy application ``` cd "BlueprintBaseName.1/src/BlueprintBaseName.1" dotnet lambda deploy-serverless ```