Skip to content

Commit 48a3d87

Browse files
committed
Update EmptyServerless templates to use annotations, and remove preview messaging from annotations template
1 parent 1a6c8f5 commit 48a3d87

File tree

21 files changed

+448
-104
lines changed

21 files changed

+448
-104
lines changed

Blueprints/BlueprintDefinitions/vs2022/AnnotationsFramework/blueprint-manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"display-name": "Annotations Framework",
2+
"display-name": "Annotations Framework Sample",
33
"system-name": "Annotations",
4-
"description": "(Preview) Use the .NET Lambda Annotations framework to write Lambda Functions.",
4+
"description": "Use the .NET Lambda Annotations framework to write Lambda Functions. This is a sample application demonstrating usage of the annotation framework, as opposed to an empty project template.",
55
"sort-order": 120,
66
"hidden-tags": [
77
"C#",

Blueprints/BlueprintDefinitions/vs2022/AnnotationsFramework/template/.template.config/template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"Lambda",
66
"Serverless"
77
],
8-
"name": "Lambda Annotations Framework (Preview)",
8+
"name": "Lambda Annotations Framework",
99
"identity": "AWS.Lambda.Serverless.Annotations.CSharp",
1010
"groupIdentity": "AWS.Lambda.Serverless.Annotations",
1111
"shortName": "serverless.Annotations",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace BlueprintBaseName._1
2+
{
3+
/// <summary>
4+
/// The implementation of <see cref="ICalculatorService"/>
5+
/// that will be used by our Lambda functions.
6+
/// </summary>
7+
public class CalculatorService : ICalculatorService
8+
{
9+
/// <inheritdoc/>
10+
public int Add(int x, int y)
11+
{
12+
return x + y;
13+
}
14+
15+
/// <inheritdoc/>
16+
public int Subtract(int x, int y)
17+
{
18+
return x - y;
19+
}
20+
21+
/// <inheritdoc/>
22+
public int Multiply(int x, int y)
23+
{
24+
return x * y;
25+
}
26+
27+
/// <inheritdoc/>
28+
public int Divide(int x, int y)
29+
{
30+
return x / y;
31+
}
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
namespace BlueprintBaseName._1
2+
{
3+
/// <summary>
4+
/// An interface for a service that implements the business logic of our Lambda functions
5+
/// </summary>
6+
public interface ICalculatorService
7+
{
8+
/// <summary>
9+
/// Adds x and y together
10+
/// </summary>
11+
/// <param name="x">Addend</param>
12+
/// <param name="y">Addend</param>
13+
/// <returns>Sum of x and y</returns>
14+
int Add(int x, int y);
15+
16+
/// <summary>
17+
/// Subtracts y from x
18+
/// </summary>
19+
/// <param name="x">Minuend</param>
20+
/// <param name="y">Subtrahend</param>
21+
/// <returns>x - y</returns>
22+
int Subtract(int x, int y);
23+
24+
/// <summary>
25+
/// Multiplies x and y
26+
/// </summary>
27+
/// <param name="x">Multiplicand</param>
28+
/// <param name="y">Multiplier</param>
29+
/// <returns>x * y</returns>
30+
int Multiply(int x, int y);
31+
32+
/// <summary>
33+
/// Divides x by y
34+
/// </summary>
35+
/// <param name="x">Dividend</param>
36+
/// <param name="y">Divisor</param>
37+
/// <returns>x / y</returns>
38+
int Divide(int x, int y);
39+
}
40+
}

Blueprints/BlueprintDefinitions/vs2022/AnnotationsFramework/template/src/BlueprintBaseName.1/Functions.cs

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,29 @@
77
namespace BlueprintBaseName._1
88
{
99
/// <summary>
10-
/// A collection of sample Lambda functions that provide a REST api for doing simple math calculations.
10+
/// A collection of sample Lambda functions that provide a REST API for doing simple math calculations.
1111
/// </summary>
1212
public class Functions
1313
{
14+
private ICalculatorService _calculatorService;
15+
1416
/// <summary>
1517
/// Default constructor.
1618
/// </summary>
17-
public Functions()
19+
/// <remarks>
20+
/// The <see cref="ICalculatorService"/> implementation that we
21+
/// instantiated in <see cref="Startup"/> will be injected here.
22+
///
23+
/// As an alternative, a dependency could be injected into each
24+
/// Lambda function handler via the [FromServices] attribute.
25+
/// </remarks>
26+
public Functions(ICalculatorService calculatorService)
1827
{
28+
_calculatorService = calculatorService;
1929
}
2030

2131
/// <summary>
2232
/// Root route that provides information about the other requests that can be made.
23-
///
24-
/// PackageType is currently required to be set to LambdaPackageType.Image till the upcoming .NET 6 managed
25-
/// runtime is available. Once the .NET 6 managed runtime is available PackageType will be optional and will
26-
/// default to Zip.
2733
/// </summary>
2834
/// <returns>API descriptions.</returns>
2935
[LambdaFunction()]
@@ -42,10 +48,6 @@ public string Default()
4248

4349
/// <summary>
4450
/// Perform x + y
45-
///
46-
/// PackageType is currently required to be set to LambdaPackageType.Image till the upcoming .NET 6 managed
47-
/// runtime is available. Once the .NET 6 managed runtime is available PackageType will be optional and will
48-
/// default to Zip.
4951
/// </summary>
5052
/// <param name="x"></param>
5153
/// <param name="y"></param>
@@ -54,16 +56,14 @@ public string Default()
5456
[HttpApi(LambdaHttpMethod.Get, "/add/{x}/{y}")]
5557
public int Add(int x, int y, ILambdaContext context)
5658
{
57-
context.Logger.LogInformation($"{x} plus {y} is {x + y}");
58-
return x + y;
59+
var sum = _calculatorService.Add(x, y);
60+
61+
context.Logger.LogInformation($"{x} plus {y} is {sum}");
62+
return sum;
5963
}
6064

6165
/// <summary>
6266
/// Perform x - y.
63-
///
64-
/// PackageType is currently required to be set to LambdaPackageType.Image till the upcoming .NET 6 managed
65-
/// runtime is available. Once the .NET 6 managed runtime is available PackageType will be optional and will
66-
/// default to Zip.
6767
/// </summary>
6868
/// <param name="x"></param>
6969
/// <param name="y"></param>
@@ -72,16 +72,14 @@ public int Add(int x, int y, ILambdaContext context)
7272
[HttpApi(LambdaHttpMethod.Get, "/subtract/{x}/{y}")]
7373
public int Subtract(int x, int y, ILambdaContext context)
7474
{
75-
context.Logger.LogInformation($"{x} subtract {y} is {x - y}");
76-
return x - y;
75+
var difference = _calculatorService.Subtract(x, y);
76+
77+
context.Logger.LogInformation($"{x} subtract {y} is {difference}");
78+
return difference;
7779
}
7880

7981
/// <summary>
8082
/// Perform x * y.
81-
///
82-
/// PackageType is currently required to be set to LambdaPackageType.Image till the upcoming .NET 6 managed
83-
/// runtime is available. Once the .NET 6 managed runtime is available PackageType will be optional and will
84-
/// default to Zip.
8583
/// </summary>
8684
/// <param name="x"></param>
8785
/// <param name="y"></param>
@@ -90,16 +88,14 @@ public int Subtract(int x, int y, ILambdaContext context)
9088
[HttpApi(LambdaHttpMethod.Get, "/multiply/{x}/{y}")]
9189
public int Multiply(int x, int y, ILambdaContext context)
9290
{
93-
context.Logger.LogInformation($"{x} multiply {y} is {x * y}");
94-
return x * y;
91+
var product = _calculatorService.Multiply(x, y);
92+
93+
context.Logger.LogInformation($"{x} multiplied by {y} is {product}");
94+
return product;
9595
}
9696

9797
/// <summary>
9898
/// Perform x / y.
99-
///
100-
/// PackageType is currently required to be set to LambdaPackageType.Image till the upcoming .NET 6 managed
101-
/// runtime is available. Once the .NET 6 managed runtime is available PackageType will be optional and will
102-
/// default to Zip.
10399
/// </summary>
104100
/// <param name="x"></param>
105101
/// <param name="y"></param>
@@ -108,8 +104,10 @@ public int Multiply(int x, int y, ILambdaContext context)
108104
[HttpApi(LambdaHttpMethod.Get, "/divide/{x}/{y}")]
109105
public int Divide(int x, int y, ILambdaContext context)
110106
{
111-
context.Logger.LogInformation($"{x} divide {y} is {x / y}");
112-
return x / y;
107+
var quotient = _calculatorService.Divide(x, y);
108+
109+
context.Logger.LogInformation($"{x} divided by {y} is {quotient}");
110+
return quotient;
113111
}
114112
}
115113
}

Blueprints/BlueprintDefinitions/vs2022/AnnotationsFramework/template/src/BlueprintBaseName.1/Readme.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# .NET Lambda Annotations Framework (Preview)
2-
3-
The Lambda Annotations framework is currently in **preview**. Development for this framework is being done on the [aws/aws-lambda-dotnet](https://github.com/aws/aws-lambda-dotnet) repository. We would appreciate any feedback or feature suggestions on this library.
1+
# .NET Lambda Annotations Framework
42

53
Lambda Annotations is a programming model for writing .NET Lambda function. At a high level the programming model allows
64
idiomatic .NET coding patterns and uses [C# Source Generators](https://docs.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview) to bridge the gap between the Lambda programming model to the more .NET idiomatic programming model.
75

6+
This template uses Lambda Annotations to deploy an HTTP API backed by multiple Lambda functions. This is intended as a sample application demonstrating usage of the annotation framework, as opposed to an empty project template.
7+
88
Here is a simplistic example of a .NET Lambda function that acts like a calculator plus method using the normal
99
Lambda programming model. It responds to an API Gateway REST API, pulls the operands from the resource paths, does the
1010
addition and returns back an API Gateway response.
@@ -59,7 +59,7 @@ public class Functions
5959
To bridge the gap from Lambda Annotations programming model to the normal programming model a .NET source generator is included in this package.
6060
After adding the attributes to your .NET code the source generator will generate the translation code between the 2 programming models. It will also
6161
keep in sync the generated information including a new function handler string into the CloudFormation template. The usage of source
62-
generator is transparent to the user.
62+
generator is transparent to the user. The source generator supports syncing of both JSON and YAML CloudFormation templates.
6363

6464
To see the code that is generated by the source generator turn the verbosity to detailed when executing a build. From the command this
6565
is done by using the `--verbosity` switch.
@@ -105,7 +105,7 @@ public class Functions
105105

106106

107107
[LambdaFunction]
108-
[HttpApi(HttpMethod.Put, HttpApiVersion.V2, "/process/{name}")]
108+
[HttpApi(LambdaHttpMethod.Put, "/process/{name}", Version = HttpApiVersion.V2)]
109109
public async Task Process([FromServices] ITracker tracker, string name, [FromBody] string data)
110110
{
111111
tracker.Record();
@@ -151,4 +151,12 @@ parameter to the `LambdaFunction` must be the event object and the event source
151151
* FromBody
152152
* Map method parameter to HTTP request body. If parameter is a complex type then request body will be assumed to be JSON and deserialized into the type.
153153
* FromServices
154-
* Map method parameter to registered service in IServiceProvider.
154+
* Map method parameter to registered service in IServiceProvider.
155+
156+
## Project References
157+
158+
If you are using API Gateway event attributes, such as `RestAPI` or `HttpAPI`, you need to manually add a package reference to `Amazon.Lambda.APIGatewayEvents` in your project, otherwise the project will not compile. We do not include it by default in order to keep the `Amazon.Lambda.Annotations` library lightweight.
159+
160+
This release only supports API Gateway Events. As we add support for other types of events, such as S3 or DynamoDB, the list of required package references will depend on the Lambda .NET attributes you are using.
161+
162+
**Note**: If you are using [dependency injection](#dependency-injection) to write functions for other service events , such as S3 or DynamoDB, you will need to reference these packages in your project as well

Blueprints/BlueprintDefinitions/vs2022/AnnotationsFramework/template/src/BlueprintBaseName.1/Startup.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using Microsoft.Extensions.DependencyInjection;
2-
31
namespace BlueprintBaseName._1
42
{
53
[Amazon.Lambda.Annotations.LambdaStartup]
@@ -15,6 +13,9 @@ public class Startup
1513
/// </summary>
1614
public void ConfigureServices(IServiceCollection services)
1715
{
16+
// Here we'll add an instance of our calculator service that be used by each function
17+
services.AddSingleton<ICalculatorService>(new CalculatorService());
18+
1819
//// Example of creating the IConfiguration object and
1920
//// adding it to the dependency injection container.
2021
//var builder = new ConfigurationBuilder()

Blueprints/BlueprintDefinitions/vs2022/AnnotationsFramework/template/test/BlueprintBaseName.1.Tests/BlueprintBaseName.1.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<PackageReference Include="Amazon.Lambda.TestUtilities" Version="2.0.0" />
1010
<PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.5.0" />
1111
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
12+
<PackageReference Include="Moq" Version="4.18.2" />
1213
<PackageReference Include="xunit" Version="2.4.1" />
1314
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
1415
</ItemGroup>

Blueprints/BlueprintDefinitions/vs2022/AnnotationsFramework/template/test/BlueprintBaseName.1.Tests/FunctionTest.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
using Xunit;
22
using Amazon.Lambda.TestUtilities;
3+
using Moq;
4+
35

46
namespace BlueprintBaseName._1.Tests
57
{
68
public class FunctionTest
79
{
10+
ICalculatorService _mockCalculatorService;
11+
812
public FunctionTest()
913
{
14+
// This isn't an accurate calculator, but rather shows how the business logic
15+
// for our Lambda functions can be moved to a class that can be replaced by a
16+
// mocked implementation for testing.
17+
var mock = new Mock<ICalculatorService>();
18+
mock.Setup(m => m.Add(It.IsAny<int>(), It.IsAny<int>())).Returns(12);
19+
20+
_mockCalculatorService = mock.Object;
1021
}
1122

1223
[Fact]
1324
public void TestAdd()
1425
{
1526
TestLambdaContext context = new TestLambdaContext();
1627

17-
var functions = new Functions();
28+
var functions = new Functions(_mockCalculatorService);
1829
Assert.Equal(12, functions.Add(3, 9, context));
1930
}
2031
}

Blueprints/BlueprintDefinitions/vs2022/EmptyServerless-Image/template/src/BlueprintBaseName.1/BlueprintBaseName.1.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
<PublishReadyToRun>true</PublishReadyToRun>
1212
</PropertyGroup>
1313
<ItemGroup>
14+
<PackageReference Include="Amazon.Lambda.Annotations" Version="0.6.0-preview" />
1415
<PackageReference Include="Amazon.Lambda.Core" Version="2.1.0" />
1516
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.3.0" />
1617
<PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.5.0" />
18+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
1719
</ItemGroup>
1820
</Project>

Blueprints/BlueprintDefinitions/vs2022/EmptyServerless-Image/template/src/BlueprintBaseName.1/Function.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Net;
22
using Amazon.Lambda.Core;
33
using Amazon.Lambda.APIGatewayEvents;
4+
using Amazon.Lambda.Annotations;
5+
using Amazon.Lambda.Annotations.APIGateway;
46

57
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
68
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
@@ -20,11 +22,23 @@ public Functions()
2022
/// <summary>
2123
/// A Lambda function to respond to HTTP Get methods from API Gateway
2224
/// </summary>
23-
/// <param name="request"></param>
24-
/// <returns>The API Gateway response.</returns>
25-
public APIGatewayProxyResponse Get(APIGatewayProxyRequest request, ILambdaContext context)
25+
/// <remarks>
26+
/// This uses the <see href="https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Annotations/README.md">Lambda Annotations</see>
27+
/// programming model to bridge the gap between the Lambda programming model and a more idiomatic .NET model.
28+
///
29+
/// This automatically handles reading parameters from an APIGatewayProxyRequest
30+
/// as well as syncing the function definitions to serverless.template each time you build.
31+
///
32+
/// If you do not wish to use this model and need to manipulate the API Gateway
33+
/// objects directly, see the accompanying Readme.md for instructions.
34+
/// </remarks>
35+
/// <param name="context">Information about the invocation, function, and execution environment</param>
36+
/// <returns>The response as an <see cref="APIGatewayProxyResponse"/></returns>
37+
[LambdaFunction(PackageType = LambdaPackageType.Image, Policies = "AWSLambdaBasicExecutionRole", MemorySize = 256, Timeout = 30)]
38+
[RestApi(LambdaHttpMethod.Get, "/")]
39+
public APIGatewayProxyResponse Get(ILambdaContext context)
2640
{
27-
context.Logger.LogInformation("Get Request\n");
41+
context.Logger.LogInformation("Handling the 'Get' Request");
2842

2943
var response = new APIGatewayProxyResponse
3044
{
@@ -35,4 +49,4 @@ public APIGatewayProxyResponse Get(APIGatewayProxyRequest request, ILambdaContex
3549

3650
return response;
3751
}
38-
}
52+
}

0 commit comments

Comments
 (0)