Introduction: Why Serverless and C# Are a Perfect Pair
\nServerless architecture (or serverless computing) is a model where you write code without worrying about managing servers. AWS Lambda is one of the most popular services for running such code. Combined with C# (.NET), you get a powerful, type-safe, and high-performance tool for creating microservices, API handlers, and background tasks.
\nIn this article, we will cover the entire journey: from environment setup to deployment and monitoring of your first C# function on AWS Lambda. The material is suitable for both beginners and experienced developers looking to systematize their knowledge.
\n\n1. Environment Setup and Project Creation
\n1.1 Installing Tools
\nTo work with C# and AWS Lambda, you will need:
\n- \n
- .NET SDK (8.0 or 6.0) — download from dotnet.microsoft.com; \n
- AWS CLI — for managing resources from the terminal; \n
- Amazon.Lambda.Tools — a global .NET tool for deployment. \n
Install Lambda Tools with a single command:
\ndotnet tool install -g Amazon.Lambda.Tools\n\n1.2 Creating a Function Template
\nUse the built-in template for a quick start:
\ndotnet new lambda.EmptyFunction --name MyFirstLambda --profile default --region us-east-1\nThis command will create a project with the Function.cs file and aws-lambda-tools-defaults.json for deployment settings.
2. Writing Serverless Function Code in C#
\n2.1 Basic Lambda Function Structure
\nEach Lambda function is a method that accepts an event object and an execution context. Let's look at a simple example:
\nusing Amazon.Lambda.Core;\nusing Amazon.Lambda.SQSEvents;\n\n[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]\n\npublic class Function\n{\n public async Task<string> FunctionHandler(SQSEvent evnt, ILambdaContext context)\n {\n context.Logger.LogInformation("Received messages: " + evnt.Records.Count);\n \n foreach (var record in evnt.Records)\n {\n await ProcessMessageAsync(record.Body, context);\n }\n \n return "Processed " + evnt.Records.Count + " messages";\n }\n\n private async Task ProcessMessageAsync(string messageBody, ILambdaContext context)\n {\n context.Logger.LogInformation("Processing: " + messageBody);\n await Task.Delay(100); // Simulating work\n }\n}\nNote the LambdaSerializer attribute — it specifies how to serialize/deserialize JSON. For C#, SystemTextJson is recommended.
2.2 Working with Different Triggers
\nAWS Lambda supports many event sources. Here's an example for an HTTP request via API Gateway:
\npublic async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)\n{\n var name = request.QueryStringParameters?.ContainsKey("name") == true \n ? request.QueryStringParameters["name"] \n : "world";\n \n var responseBody = $"Hello, {name}!";\n \n return new APIGatewayProxyResponse\n {\n StatusCode = 200,\n Body = responseBody,\n Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }\n };\n}\nTo work with HTTP, you will need to install the Amazon.Lambda.APIGatewayEvents package.
3. Deploying and Testing the Function
\n3.1 Local Testing
\nBefore deployment, test your code locally using dotnet lambda invoke:
dotnet lambda invoke --payload "{\\"Records\