いわさです。
.NET Lambda で利用出来るフレームワークに Lambda Annotaions Framework というものがあります。
2022 年 4 月に AWS 公式ブログで紹介されたもので、.NET を Lambda で使用するとどうしてもインターフェースなどに冗長な記述が発生してしまうのですが、C# のソースコードジェネレータの仕組みを使ってそのあたりをうまく隠蔽してくれるフレームワークです。
これまでずっとプレビューという位置づけだったのですが、つい先日 GA になったとアップデートアナウンスがありました。
Lambda Annotations Framework の概要
アノテーションというのは、C# の文脈でいうとクラスやメソッドに付与出来るメタデータ・属性を指しています。
色々な用途で使われるのですが、ビルド時やあるいは実行時に動的に何かカスタム処理を行う際に利用されることが多いです。
Lambda Annotations Framework を使わない場合、例えば API Gateway と Lambda を統合する場合であれば次のような実装が従来必要です。
Functions.cs
public class Functions
{
public APIGatewayProxyResponse LambdaMathPlus(APIGatewayProxyRequest request, ILambdaContext context)
{
if (!request.PathParameters.TryGetValue("x", out var xs))
{
return new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.BadRequest
};
}
if (!request.PathParameters.TryGetValue("y", out var ys))
{
return new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.BadRequest
};
}
var x = int.Parse(xs);
var y = int.Parse(ys);
return new APIGatewayProxyResponse
{
StatusCode = (int)HttpStatusCode.OK,
Body = (x + y).ToString(),
Headers = new Dictionary<string, string> { { "Content-Type", "text/plain" } }
};
}
}
ビジネスロジックと関係ないコード多すぎ問題が発生します。
これを次のように、今回 GA となったフレームワークのアノテーションを使うことでとてもシンプルに実装出来るようになります。
public class Functions
{
[LambdaFunction]
[RestApi("/plus/{x}/{y}")]
public int Plus(int x, int y)
{
return x + y;
}
}
実際にはコンパイル時に上記メタデータを検出して、本来必要だった冗長なコードを自動生成してくれるような仕組みとなっています。
NuGet パッケージマネージャーから導入することも出来ますし、Visual Studio や .NET CLI のテンプレートとしても提供されているので簡単に使い始めることが出来ます。
変更点を確認
導入や使用方法は 2022 年 12 月に次の記事で紹介していますのでこちらを見てもらえると。
フレームワークの概念自体はそのころと全く変わっていないです。
アップデート方法
既にプレビュー版を導入済みだった方はアップデートが必要です。
Amazon.Lambda.Tools
とAmazon.Lambda.Templates
をアップデートしましょう。
% dotnet tool update -g Amazon.Lambda.Tools
Tool 'amazon.lambda.tools' was successfully updated from version '5.6.3' to version '5.7.2'.
% dotnet new install Amazon.Lambda.Templates::6.14.0
The following template packages will be installed:
Amazon.Lambda.Templates::6.14.0
Amazon.Lambda.Templates (version 6.10.0) is already installed, it will be replaced with version 6.14.0.
Amazon.Lambda.Templates::6.10.0 was successfully uninstalled.
Success: Amazon.Lambda.Templates::6.14.0 installed the following templates:
Template Name Short Name Language Tags
--------------------------------------------------------------------------------- -------------------------------------------- -------- --------------------------------
Empty Top-level Function lambda.EmptyTopLevelFunction [C#] AWS/Lambda/Serverless
Lambda Annotations Framework Sample serverless.Annotations [C#] AWS/Lambda/Serverless
Lambda ASP.NET Core Minimal API serverless.AspNetCoreMinimalAPI [C#] AWS/Lambda/Serverless
Lambda ASP.NET Core Web API serverless.AspNetCoreWebAPI [C#],F# AWS/Lambda/Serverless
Lambda ASP.NET Core Web API (.NET 6 Container Image) serverless.image.AspNetCoreWebAPI [C#],F# AWS/Lambda/Serverless
Lambda ASP.NET Core Web Application with Razor Pages serverless.AspNetCoreWebApp [C#] AWS/Lambda/Serverless
Lambda Custom Runtime Function (.NET 7) lambda.CustomRuntimeFunction [C#],F# AWS/Lambda/Function
Lambda Detect Image Labels lambda.DetectImageLabels [C#],F# AWS/Lambda/Function
Lambda Empty Function lambda.EmptyFunction [C#],F# AWS/Lambda/Function
Lambda Empty Function (.NET 7 Container Image) lambda.image.EmptyFunction [C#],F# AWS/Lambda/Function
Lambda Empty Serverless serverless.EmptyServerless [C#],F# AWS/Lambda/Serverless
:
テンプレートからもPreview
の表記がなくなりました。
アップデート内容
前回の記事が0.10.0-preview
時点のもので、それから毎月定期的にアップデートされているようです。
更新内容をサマリしてみました。
IHttpResult と HttpResults タイプを使ったステータスコードとヘッダーのレスポンスカスタマイズをサポート
次のようにメソッドの返却値に IHttpResult が使えるようになっていますね。
[LambdaFunction(PackageType = LambdaPackageType.Image)]
[HttpApi(LambdaHttpMethod.Get, "/resource/{id}")]
public IHttpResult NotFoundResponseWithHeaderV2(int id, ILambdaContext context)
{
return HttpResults.NotFound($"Resource with id {id} could not be found")
.AddHeader("Custom-Header1", "Value1");
}
aws-lambda-dotnet/Libraries/src/Amazon.Lambda.Annotations at master · aws/aws-lambda-dotnet より
また、上記が実装された際には 5xx エラーを返却する方法がなく、結局 APIGatewayProxyResponse を使わざるを得ないケースがあったのですが、HttpResults.InternalServerError
が使用出来るようになったので、サーバーエラーを直感的に処理出来るようにもアップデートされています。
[LambdaFunction(PackageType = LambdaPackageType.Image)]
[HttpApi(LambdaHttpMethod.Get, "/resource/{id}")]
public IHttpResult NotFoundResponseWithHeaderV2(int id, ILambdaContext context)
{
try
{
//hoge process
return HttpResults.NotFound($"Resource with id {id} could not be found")
.AddHeader("Custom-Header1", "Value1");
}
catch (Exception e)
{
return HttpResults.InternalServerError("hoge error");
}
}
また、IHttpResult
からステータスコードを取得出来るようにも修正されているので関数をテストするコードでステータスを参照することも出来るようになっています。
public class HtttpResultsStatusCodeUsage
{
[Fact]
public void UsageOfIHttpResultStatusCode()
{
var sut = new Functions();
var result = sut.NotFoundResponseWithHeaderV2(1, null);
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
}
}
バグの修正や安定性の向上
コードジェネレータによる生成失敗時にエラー内容が正しく報告されない問題などがありましたが修正されています。
また、診断メッセージ自体にもフォーマット崩れなどの問題がありましたが、それも解消しています。
診断メッセージ関係の小さなアップデートが多く、トラブルシューティングしやすくなっていそうです。
静的チェック機能の強化
コンパイルにあたっていくつかの前提条件がありますが、コンパイルエラーで検出出来るように強化されています。
例えばアセンブリ属性にLambdaSerailizerAttribute
が指定されていない場合や、API Gateway 使用時にAmazon.Lambda.APIGatewayEvents
が参照されていない場合などはコンパイルエラーとなります。
さいごに
本日は Lambda Annotations Framework for .NET が GA となったのでプレビューからの変更点を確認してみました。
まず、GA ということでプロダクトでも採用しやすくなったと思います。
プレビュー時には破壊的なアップデートがあったりしましたが、これからはより安定した形で導入しやすくなったのではないでしょうか。
前回紹介した時からの変更点としては各種安定性が向上した他に、IHttpResult
をつかって ASP.NET に近い形で HTTP レスポンスが表現出来るようになった点でしょうか。