using Amazon.Lambda.Core; using Amazon.Lambda.RuntimeSupport; using Amazon.Lambda.Serialization.SystemTextJson; using Amazon.Lambda.APIGatewayEvents; using System.Text.Json.Serialization; using System.Net; namespace BlueprintBaseName._1; public class Functions { /// /// The main entry point for the Lambda function. The main function is called once during the Lambda init phase. It /// initializes the .NET Lambda runtime client passing in the function handler to invoke for each Lambda event and /// the JSON serializer to use for converting Lambda JSON format to the .NET types. /// private static async Task Main() { // The "_HANDLER" environment variable is set by the Lambda runtime to the configured value for the function // handler property. var configuredFunctionHandler = Environment.GetEnvironmentVariable("_HANDLER"); // Native AOT Lambda functions are deployed as a native executable using the provided.al2 Lambda runtime. // The provided.al2 runtime ignores the function handler field and always looks for an executable called "bootstrap". // // As a convention this project template checks the value for the function handler field set in the // serverless template to determine which method should be registered with the Lambda runtime client // to respond to incoming Lambda events. This allows multiple Lambda functions be defined in the // same .NET project using the provided.al2 runtime. Func handler = configuredFunctionHandler switch { nameof(GetFunctionHandler) => new Functions().GetFunctionHandler, nameof(PutFunctionHandler) => new Functions().PutFunctionHandler, _ => throw new Exception($"Unknown method to call for handler value {configuredFunctionHandler}") }; await LambdaBootstrapBuilder.Create(handler, new SourceGeneratorLambdaJsonSerializer()) .Build() .RunAsync(); } /// /// A Lambda function to respond to HTTP Get methods from API Gateway. /// /// To use this handler to respond to an AWS event, reference the appropriate package from /// https://github.com/aws/aws-lambda-dotnet#events /// and change the input parameter to the desired event type. When the event type /// is changed, the handler type registered in the main method needs to be updated and the LambdaFunctionJsonSerializerContext /// defined below will need the JsonSerializable updated. If the return type and event type are different then the /// LambdaFunctionJsonSerializerContext must have two JsonSerializable attributes, one for each type. /// // When using Native AOT extra testing with the deployed Lambda functions is required to ensure // the libraries used in the Lambda function work correctly with Native AOT. If a runtime // error occurs about missing types or methods the most likely solution will be to remove references to trim-unsafe // code or configure trimming options. This sample defaults to partial TrimMode because currently the AWS // SDK for .NET does not support trimming. This will result in a larger executable size, and still does not // guarantee runtime trimming errors won't be hit. /// /// /// /// public APIGatewayProxyResponse GetFunctionHandler(APIGatewayProxyRequest request, ILambdaContext context) { context.Logger.LogInformation("Get Request\n"); var response = new APIGatewayProxyResponse { StatusCode = (int)HttpStatusCode.OK, Body = "Hello AWS Serverless", Headers = new Dictionary { { "Content-Type", "text/plain" } } }; return response; } /// /// A Lambda function to respond to HTTP PUT methods from API Gateway /// /// To use this handler to respond to an AWS event, reference the appropriate package from /// https://github.com/aws/aws-lambda-dotnet#events /// and change the input parameter to the desired event type. When the event type /// is changed the handler type registered in the main needs to be updated and the LambdaFunctionJsonSerializerContext /// defined below will need the JsonSerializable updated. If the return type and event type are different then the /// LambdaFunctionJsonSerializerContext must have two JsonSerializable attributes, one for each type. /// // When using Native AOT extra testing with the deployed Lambda functions is required to ensure // the libraries used in the Lambda function work correctly with Native AOT. If a runtime // error occurs about missing types or methods the most likely solution will be to remove references to trim-unsafe // code or configure trimming options. This sample defaults to partial TrimMode because currently the AWS // SDK for .NET does not support trimming. This will result in a larger executable size, and still does not // guarantee runtime trimming errors won't be hit. /// /// /// /// public APIGatewayProxyResponse PutFunctionHandler(APIGatewayProxyRequest request, ILambdaContext context) { context.Logger.LogInformation("Put Request"); var response = new APIGatewayProxyResponse { StatusCode = (int)HttpStatusCode.OK, Body = "Processed PUT request", Headers = new Dictionary { { "Content-Type", "text/plain" } } }; return response; } } /// /// This class is used to register the input event and return type for the FunctionHandler method with the System.Text.Json source generator. /// There must be a JsonSerializable attribute for each type used as the input and return type or a runtime error will occur /// from the JSON serializer unable to find the serialization information for unknown types. /// [JsonSerializable(typeof(APIGatewayProxyRequest))] [JsonSerializable(typeof(APIGatewayProxyResponse))] public partial class LambdaFunctionJsonSerializerContext : JsonSerializerContext { // By using this partial class derived from JsonSerializerContext, we can generate reflection free JSON Serializer code at compile time // which can deserialize our class and properties. However, we must attribute this class to tell it what types to generate serialization code for. // See https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-source-generation }