Hello, .NET Lambda Annotations
Getting Started with .NET on AWS: Lambda Annotations
Table of contents
- This episode: .NET Lambda Annotations Framework and simplified coding of HTTP endpoints. In this Hello, Cloud blog series, we're covering the basics of AWS cloud services for newcomers who are .NET developers. If you love C# but are new to AWS, or to this particular service, this should give you a jumpstart.
- .NET Lambda Annotations Framework: What is it, and why use It?
- Our Hello, Lambda Annotations Project
This episode: .NET Lambda Annotations Framework and simplified coding of HTTP endpoints. In this Hello, Cloud blog series, we're covering the basics of AWS cloud services for newcomers who are .NET developers. If you love C# but are new to AWS, or to this particular service, this should give you a jumpstart.
In this post we'll introduce The .NET Lambda Annotations Framework and use it in a "Hello, Cloud" .NET program to create an API for date operations. We'll do this step-by-step, making no assumptions other than familiarity with C# and Visual Studio. We're using Visual Studio 2022 and .NET 6.
.NET Lambda Annotations Framework: What is it, and why use It?
"Simple ingredients prepared in a simple way - that's the best way to take your everyday cooking to a higher level." —Jose Andres
AWS Lambda is a serverless, event-driven compute service that has propelled the serverless revolution. Lambda handles all the administration of compute resources, and you only pay for requests and compute time. Programming-wise, you just supply the code, which are functions. It's hard to imagine things getting much simpler.
And yet, there is room for improvement. You normally write handler functions for AWS Lambda that take 2 parameters, an event object and an ILambdaContext
parameter used for logging. If you're writing Lambda functions for an HTTP API, you've got to pull your HTTP endpoint parameters out of a APIGatewayHttpApiV2ProxyRequest
object. Sometimes, that code is longer than the actual function logic itself.
.NET Lambda Annotations Framework (hereafter "Lambda Annotations"), also known as Amazon.Lambda.Annotations, is a nuget package for writing Lambda functions. AWS describes it as "a programming model for writing .NET Lambda functions that allows idiomatic .NET coding patterns".
Traditional vs. Annotated Lambda Functions
Let's consider an example from the framework's announcement blog post by Norm Johanson. The function below implements an API Gateway endpoint that expects x and y integer parameters from a request and returns their sum. Of the 22 lines in the body, 21 of them are dedicated to parameter extraction and the return object. There's just one statement performing the function logic.
public APIGatewayHttpApiV2ProxyResponse LambdaMathAdd(APIGatewayHttpApiV2ProxyRequest request, ILambdaContext context)
{
if (!request.PathParameters.TryGetValue("x", out var xs))
{
return new APIGatewayHttpApiV2ProxyResponse
{
StatusCode = (int)HttpStatusCode.BadRequest
};
}
if (!request.PathParameters.TryGetValue("y", out var ys))
{
return new APIGatewayHttpApiV2ProxyResponse
{
StatusCode = (int)HttpStatusCode.BadRequest
};
}
var x = int.Parse(xs);
var y = int.Parse(ys);
return new APIGatewayHttpApiV2ProxyResponse
{
StatusCode = (int)HttpStatusCode.OK,
Body = (x + y).ToString(),
Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }
};
}
Now, let's contrast that to an equivalent function written using .NET Lambda Annotations. This much shorter function has just one statement which performs the logic, and some attributes. The attributes are the "annotations" the framework allows us to write. The [LambdaFunction]
attribute identifies this as a Lambda function, and the [HttpApi...]
attribute defines an HTTP API endpoint for a GET method and its path. This function concerns itself only with the parameters and return type it needs to deal with, and doesn't have to worry about the plumbing. There's no need to write a Lambda function handler and work with APIGatewayHttpApiV2ProxyRequest
, ILambdaContext
, and APIGatewayHttpApiV2ProxyResponse
objects.
[LambdaFunction]
[HttpApi(LambdaHttpMethod.Get, "/add/{x}/{y}")]
public int Add(int x, int y)
{
return x + y;
}
In summary, this annotated function is a more natural way to code an HTTP endpoint method in C#. But, you ask, don't we need all those things that went away? We do indeed, but they are created for you. Under the hood, when you build the program, code is generated that translates between the code you've written and what Lambda functions need. The project's CloudFormation template gets updated as well.
Our Hello, Lambda Annotations Project
In this tutorial, we'll create an API for date operations, defining several HTTP endpoints in one source file. We'll end up with a datediff/from/to
function that returns the number of days between 2 dates, and a dateadd/date/days
function that adds a certain number of days to a date and returns the new date.
One-time Setup
For any of the tutorials in the Hello, Cloud series you need the following:
An AWS account, and an understanding of what is included in the AWS Free Tier.
Microsoft Visual Studio 2022. If you're using an older version of Visual Studio you won't be able to use .NET 6. If you use a different IDE, you may have to find alternatives to some tutorial steps.
AWS Toolkit for Visual Studio. You'll need to configure the toolkit to access your AWS account and create an IAM user. Your default AWS profile will be linked to this user when running programs from the command line.
Step 1: Create a Project
In this step, you'll create a new serverless application in Visual Studio using the Annotations Framework template.
Launch Visual Studio and create a new project.
Search for and select the AWS Serverless Application (.NET Core - C#) project template. Click Next.
Name your project HelloLambdaAnnotations and select a development folder. Click Create.
On the Select Blueprint dialog, search for and select the Annotations Framework blueprint. Click Finish.
Review the generated project and note the following. The project contains the Amazon.Lambda.Annotations nuget package. The Function.cs file contains sample functions for a calculator with names such as Add and Multiply.
Step 2: Code Your API Functions
In this step, you'll code your own API functions using Lambda Annotations.
Below the Default function, insert the code below at the end of this step to add two functions, DateDiff and DateAdd. DateDiff will accept two date string parameters,
from
andto
, and return the number of days difference between them. DateAdd will accept adate
anddays
parameter. It will add the days value to the original date and return a new date string.Remove the other date functions below that came with the blueprint.
Remove the Default function that came with the blueprint.
Build the program.
Function.cs code to add
using Amazon.Lambda.Core;
using Amazon.Lambda.Annotations;
using Amazon.Lambda.Annotations.APIGateway;
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace HelloLambdaAnnotations
{
/// <summary>
/// Sample Lambda functions that perform date functions.
/// </summary>
public class Functions
{
/// <summary>
/// Default constructor.
/// </summary>
public Functions()
{
}
/// <summary>
/// Compute the difference in days between two dates, from and to.
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns>number of days between from and to.</returns>
[LambdaFunction()]
[HttpApi(LambdaHttpMethod.Get, "/datediff/{from}/{to}")]
public int DateDifferenceInDays(string from, string to)
{
int days = Convert.ToInt16((DateTime.Parse(to) - DateTime.Parse(from)).TotalDays);
return days;
}
/// <summary>
/// Add a day count to a date and return the new date.
/// </summary>
/// <param name="date">starting date</param>
/// <param name="days">number of days to add</param>
/// <returns>resulting date</returns>
[LambdaFunction()]
[HttpApi(LambdaHttpMethod.Get, "/dateadd/{date}/{days}")]
public string DateAdd(string date, int days)
{
return (DateTime.Parse(date).AddDays(days)).ToShortDateString();
}
}
}
Step 3. Deploy Function to AWS Lambda
In this step you'll publish your API to AWS Lambda.
In Visual Studio Solution Explorer, right-click the
HelloLambdaAnnotations
project and select Publish to AWS Lambda...On the Publish to AWS Serverless Application wizard,
select a Region to publish to. We're using us-west-2 (Oregon).
Enter a Stack Name of HelloLambdaAnnotations.
Next to S3 Bucket, click New... and enter hello-lambda-annotations for Bucket name. Click OK.
Click Publish.
Wait for publishing to complete. When you see a Status of CREATE_COMPLETE at top, publishing is complete.
4. In the top section of the publish page, copy the AWS Serverless URL. This is the base path to your API. Ours was https://7mcinuk7u6.execute-api.us-west-2.amazonaws.com/
.
Step 4: Test the API
Now it's time to test our API endpoints.
In a browser, visit the API URL you just copied. You see an instructional page.
Test the datediff function. Add
/datediff/2022-01-01/2023-01-01
to the end of the path and hit ENTER. You should get a response of 365. Try some different date values. In our second example, we used to/datediff/1969-07-20/2023-02-12
to see how many days had elapsed since the Apollo 11 moon landing.Test the dateadd function. Change the path to
/dateadd/2022-12-25/7
and press ENTER. The function should compute that one week after Christmas 2022 is New Year's Day 2023. Try another example.
Congratulations, you've just created AWS Lambda function HTTP endpoints with the .NET Lambda Annotations Framework.
Step 5: Shut it Down
When you're done with the tutorial, delete the AWS resources.
In Visual Studio, go to AWS Explore and refresh the view.
Expand
CloudFormation
.Right-click the HelloLambdaAnnotations node and select Delete.
Where To Go From Here
In this tutorial, you saw how naturally you can express HTTP endpoints in C# with the .NET Lambda Annotations Framework. The framework uses Source Code Generators, and is not available for other .NET languages such as F#.
To go further, start using the framework for your own HTTP endpoints. Review the resources linked below for more information and tutorials. You can get a deeper explanation of the mechanics from the announcement blog by Norm Johanson.
Further Reading
AWS Documentation
AWS SDK for .NET Developer Guide: Using annotations to write AWS Lambda functions
nuget: Amazon.Lambda.Notations
Videos
Lambda Annotations Framework for .NET by James Eastham
AWS re:Invent 2022: AMster & The Brit's Code Corner: Using .NET Lambda Annotations, Pt 1
Blogs
Introducing .NET Annotations Lambda Framework by Norm Johanson
.NET Lambda Annotations Framework is now generally available by Norm Johanson
Dependency Injection with the Lambda Annotations Library for .NET - Part 1, Lambda Applications by Bryan Hogan
Dependency Injection with the Lambda Annotations Library for .NET - Part 2, Lambda Functions by Bryan Hogan
Courseware
AWS Lambda for the .NET Developer - Udemy course by Rahul Nath