Cookie の設定を選択する

当社は、当社のサイトおよびサービスを提供するために必要な必須 Cookie および類似のツールを使用しています。当社は、パフォーマンス Cookie を使用して匿名の統計情報を収集することで、お客様が当社のサイトをどのように利用しているかを把握し、改善に役立てています。必須 Cookie は無効化できませんが、[カスタマイズ] または [拒否] をクリックしてパフォーマンス Cookie を拒否することはできます。

お客様が同意した場合、AWS および承認された第三者は、Cookie を使用して便利なサイト機能を提供したり、お客様の選択を記憶したり、関連する広告を含む関連コンテンツを表示したりします。すべての必須ではない Cookie を受け入れるか拒否するには、[受け入れる] または [拒否] をクリックしてください。より詳細な選択を行うには、[カスタマイズ] をクリックしてください。

C# の Lambda 関数ハンドラーの定義

フォーカスモード
C# の Lambda 関数ハンドラーの定義 - AWS Lambda

Lambda 関数ハンドラーは、イベントを処理する関数コード内のメソッドです。関数が呼び出されると、Lambda はハンドラーメソッドを実行します。関数は、ハンドラーが応答を返すか、終了するか、タイムアウトするまで実行されます。

このページでは、プロジェクトのセットアップオプション、命名規則、ベストプラクティスなど、C# で Lambda 関数ハンドラーを使用して .NET マネージドランタイムを扱う方法について説明します。このページには、注文に関する情報を取得し、テキストファイル受信を生成して、このファイルを Amazon Simple Storage Service (S3) バケットに配置する C# Lambda 関数の例も含まれています。関数を書き込んだ後にデプロイする方法については、「.zip ファイルアーカイブを使用して C# Lambda 関数を構築し、デプロイする」または「コンテナイメージを使用して.NET の Lambda 関数をデプロイする」を参照してください。

C# ハンドラープロジェクトのセットアップ

C# で Lambda 関数を使用する場合、プロセスにはコードを記述し、コードを Lambda にデプロイする動作が含まれます。.NET で Lambda 関数をデプロイするための実行モデルには、クラスライブラリアプローチと実行可能アセンブリアプローチの 2 種類があります。

クラスライブラリアプローチでは、関数コードを .NET アセンブリ (.dll) としてパッケージ化し、.NET マネージドランタイム (dotnet8) を使用して Lambda にデプロイします。ハンドラー名として、Lambda は AssemblyName::Namespace.Classname::Methodname 形式の文字列を想定します。関数の初期化フェーズでは、関数のクラスが初期化され、コンストラクタ内のすべてのコードが実行されます。

実行可能ファイルのアセンブリアプローチでは、C# 9 で初めて導入された最上位ステートメント機能を使用します。この方法では、関数の呼び出しコマンドを受信するたびに Lambda が実行する実行可能アセンブリが生成されます。この方法では、.NET マネージドランタイム (dotnet8) も使用します。ハンドラー名として、Lambda に実行する実行可能アセンブリの名前を提示します。

このページのメインの例では、クラスライブラリ手法を示しています。C# Lambda プロジェクトはさまざまな方法で初期化できますが、最も簡単な方法は .NET CLI と Amazon.Lambda.Tools CLI を使用することです。.NET 開発環境のセットアップ の手順に従って Amazon.Lambda.Tools CLI を設定します。次に、以下のコマンドでプロジェクトを初期化します。

dotnet new lambda.EmptyFunction --name ExampleCS

このコマンドを実行すると、以下のファイル構造が生成されます。

/project-root └ src └ ExampleCS └ Function.cs (contains main handler) └ Readme.md └ aws-lambda-tools-defaults.json └ ExampleCS.csproj └ test └ ExampleCS.Tests └ FunctionTest.cs (contains main handler) └ ExampleCS.Tests.csproj

このファイル構造では、関数のメインハンドラーロジックは Function.cs ファイルにあります。

C# Lambda 関数のコードの例

以下の C# Lambda 関数コードの例では、注文に関する情報を取得し、テキストファイル受信を生成し、このファイルを Amazon S3 バケットに配置します。

Function.cs Lambda 関数
using System; using System.Text; using System.Threading.Tasks; using Amazon.Lambda.Core; using Amazon.S3; using Amazon.S3.Model; // Assembly attribute to enable Lambda function logging [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace ExampleLambda; public class Order { public string OrderId { get; set; } = string.Empty; public double Amount { get; set; } public string Item { get; set; } = string.Empty; } public class OrderHandler { private static readonly AmazonS3Client s3Client = new(); public async Task<string> HandleRequest(Order order, ILambdaContext context) { try { string? bucketName = Environment.GetEnvironmentVariable("RECEIPT_BUCKET"); if (string.IsNullOrWhiteSpace(bucketName)) { throw new ArgumentException("RECEIPT_BUCKET environment variable is not set"); } string receiptContent = $"OrderID: {order.OrderId}\nAmount: ${order.Amount:F2}\nItem: {order.Item}"; string key = $"receipts/{order.OrderId}.txt"; await UploadReceiptToS3(bucketName, key, receiptContent); context.Logger.LogInformation($"Successfully processed order {order.OrderId} and stored receipt in S3 bucket {bucketName}"); return "Success"; } catch (Exception ex) { context.Logger.LogError($"Failed to process order: {ex.Message}"); throw; } } private async Task UploadReceiptToS3(string bucketName, string key, string receiptContent) { try { var putRequest = new PutObjectRequest { BucketName = bucketName, Key = key, ContentBody = receiptContent, ContentType = "text/plain" }; await s3Client.PutObjectAsync(putRequest); } catch (AmazonS3Exception ex) { throw new Exception($"Failed to upload receipt to S3: {ex.Message}", ex); } } }

この Function.cs ファイルには以下のコードのセクションが含まれます:

  • using ステートメント: これらを使用して、Lambda 関数に必要な C# クラスをインポートします。

  • [assembly: LambdaSerializer(...)]: LambdaSerializer は、JSON イベントペイロードを関数に渡す前に C# オブジェクトに自動的に変換するよう Lambda に指示するアセンブリ属性です。

  • namespace ExampleLambda: 名前空間を定義します。C# では、名前空間名がファイル名と一致する必要はありません。

  • public class Order {...}: 予測される入力イベントの形状を定義します。

  • public class OrderHandler {...}: これは C# クラスを定義します。その中で、メインハンドラーメソッドとその他のヘルパーメソッドを定義します。

  • private static readonly AmazonS3Client s3Client = new();: これにより、メインハンドラーメソッドの外部で、デフォルトの認証情報プロバイダーチェーンを使用して Amazon S3 クライアントが初期化されます。これにより、Lambda は初期化フェーズ中にこのコードを実行します。

  • public async ... HandleRequest (Order order, ILambdaContext context): これはメインハンドラーメソッドで、メインアプリケーションロジックが含まれています。

  • private async Task UploadReceiptToS3(...) {}: これは、メイン handleRequest ハンドラーメソッドによって参照されるヘルパーメソッドです。

この関数には Amazon S3 SDK クライアントが必要なため、プロジェクトの依存関係に追加する必要があります。このためには、src/ExampleCS に移動して次のコマンドを実行することもできます。

dotnet add package AWSSDK.S3

デフォルトでは、生成された aws-lambda-tools-defaults.json ファイルには関数の profile または region 情報は含まれません。さらに、function-handler 文字列を正しい値 (ExampleCS::ExampleLambda.OrderHandler::HandleRequest) に更新します。この更新を手動で行い、関数に特定の認証情報プロファイルとリージョンを使用するために必要なメタデータを追加できます。例えば、aws-lambda-tools-defaults.json ファイルは次のようになります。

{ "Information": [ "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", "dotnet lambda help", "All the command line options for the Lambda command can be specified in this file." ], "profile": "default", "region": "us-east-1", "configuration": "Release", "function-architecture": "x86_64", "function-runtime": "dotnet8", "function-memory-size": 512, "function-timeout": 30, "function-handler": "ExampleCS::ExampleLambda.OrderHandler::HandleRequest" }

デフォルトでは、生成された aws-lambda-tools-defaults.json ファイルには関数の profile または region 情報は含まれません。さらに、function-handler 文字列を正しい値 (ExampleCS::ExampleLambda.OrderHandler::HandleRequest) に更新します。この更新を手動で行い、関数に特定の認証情報プロファイルとリージョンを使用するために必要なメタデータを追加できます。例えば、aws-lambda-tools-defaults.json ファイルは次のようになります。

{ "Information": [ "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", "dotnet lambda help", "All the command line options for the Lambda command can be specified in this file." ], "profile": "default", "region": "us-east-1", "configuration": "Release", "function-architecture": "x86_64", "function-runtime": "dotnet8", "function-memory-size": 512, "function-timeout": 30, "function-handler": "ExampleCS::ExampleLambda.OrderHandler::HandleRequest" }

この関数が正しく機能するには、実行ロールs3:PutObject アクションを許可する必要があります。dotnet lambda deploy-function コマンド (dotnet lambda deploy-function ExampleCS) を使用している場合、CLI プロンプトの AWSLambdaExecute ポリシーには、この関数を正常に呼び出すために必要なアクセス許可が含まれています。

また、以下も確認します。

最後に、必ず RECEIPT_BUCKET 環境変数を定義してください。呼び出しに成功したら、Amazon S3 バケットに受信ファイルが含まれているはずです。

クラスライブラリハンドラー

このページのメインのコード例は、クラスライブラリハンドラーを示しています。クラスライブラリハンドラーの構造は次のとおりです。

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace NAMESPACE; ... public class CLASSNAME { public async Task<string> METHODNAME (...) { ... } }

Lambda 関数を作成するときは、関数のハンドラーに関する情報をハンドラーフィールドの文字列の形式で Lambda に提供する必要があります。これにより、関数の呼び出し時に実行するコードのメソッドを Lambda に指示します。C# では、クラスライブラリハンドラーの場合、ハンドラー文字列の形式は ASSEMBLY::TYPE::METHOD です。ここでは、次のようになります。

  • ASSEMBLY は、アプリケーションの .NET アセンブリファイルの名前です。Amazon.Lambda.Tools CLI を使用してアプリケーションを構築し、.csproj ファイルの AssemblyName プロパティを使用してアセンブリ名を設定しない場合、ASSEMBLY は単に .csproj ファイルの名前になります。

  • TYPE は、ハンドラー型の正式名称で、NAMESPACE.CLASSNAME です。

  • METHOD は、コード内の関数ハンドラーメソッドの名前で、METHODNAME です。

このページのメインのコード例では、アセンブリに ExampleCS という名前が付けられている場合、完全なハンドラー文字列は ExampleCS::ExampleLambda.OrderHandler::HandleRequest です。

実行可能アセンブリハンドラー

C# の Lambda 関数を実行ファイルアセンブリとして定義することもできます。実行可能アセンブリハンドラーは、C# の最上位ステートメント機能を使用します。この機能では、コンパイラが Main() メソッドを生成し、関数コードをその中に配置します。実行可能アセンブリを使用する場合は、Lambda ランタイムをブートストラップする必要があります。これを行うには、コードで LambdaBootstrapBuilder.Create メソッドを使用します。このメソッドへの入力は、メインハンドラー関数と使用する Lambda シリアライザーです。以下は、C# の実行可能アセンブリハンドラーの例です。

namespace GetProductHandler; IDatabaseRepository repo = new DatabaseRepository(); await LambdaBootstrapBuilder.Create<APIGatewayProxyRequest>(Handler, new DefaultLambdaJsonSerializer()) .Build() .RunAsync(); async Task<APIGatewayProxyResponse> Handler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context) { var id = apigProxyEvent.PathParameters["id"]; var databaseRecord = await this.repo.GetById(id); return new APIGatewayProxyResponse { StatusCode = (int)HttpStatusCode.OK, Body = JsonSerializer.Serialize(databaseRecord) }; };

実行可能アセンブリのハンドラーフィールドでは、コードの実行方法を Lambda に指示するハンドラー文字列はアセンブリの名前です。この例では、GetProductHandler です。

C# 関数の有効なハンドラー署名

C# では、有効な Lambda ハンドラー署名は 0~2 個の引数を取ります。通常、ハンドラー署名には、メインの例に示すように、2 つの引数があります。

public async Task<string> HandleRequest(Order order, ILambdaContext context)

2 つの引数を指定する場合、最初の引数はイベント入力で、2 番目の引数は Lambda コンテキストオブジェクトである必要があります。どちらの引数もオプションです。例えば、以下も有効な C# の Lambda ハンドラー署名です。

  • public async Task<string> HandleRequest()

  • public async Task<string> HandleRequest(Order order)

  • public async Task<string> HandleRequest(ILambdaContext context)

ハンドラー署名の基本構文以外にも、いくつかの制限があります。

  • ハンドラー署名で unsafe キーワードを使用することはできません。ただし、ハンドラーメソッドとその依存関係内で unsafe コンテキストを使用できます。詳細については、Microsoft ドキュメントウェブサイトの「unsafe (C# reference)」を参照してください。

  • ハンドラーは、params キーワードを使用したり、入力または戻りパラメータとして ArgIterator を使用したりすることはできません。これらのキーワードは、可変数のパラメータをサポートします。ハンドラーが受け入れることができる引数の最大数は 2 です。

  • ハンドラーは汎用メソッドではない場合があります。つまり、<T> などの汎用型パラメータを使用することはできません。

  • Lambda は、署名に async void を持つ非同期ハンドラーをサポートしていません。

ハンドラーの命名規則

C# の Lambda ハンドラーには、厳密な命名制限はありません。ただし、関数をデプロイするときに、Lambda に正しいハンドラー文字列を指定する必要があります。適切なハンドラー文字列は、クラスライブラリハンドラー実行可能アセンブリハンドラーのどちらをデプロイするかによって異なります。

ハンドラーには任意の名前を使用できますが、C# の関数名は通常 PascalCase です。また、ファイル名はクラス名やハンドラー名と一致する必要はありませんが、クラス名が OrderHandler の場合と同様に OrderHandler.cs などのファイル名を使用するのがベストプラクティスです。例えば、この例のファイル名を Function.cs から OrderHandler.cs に変更できます。

C# Lambda 関数のシリアル化

JSON は Lambda 関数の最も一般的な標準入力形式です。この例では、関数は以下のような入力を想定しています:

{ "orderId": "12345", "amount": 199.99, "item": "Wireless Headphones" }

C# では、クラスで予想される入力イベントの形状を定義できます。この例では、この入力をモデル化する Order クラスを定義します。

public class Order { public string OrderId { get; set; } = string.Empty; public double Amount { get; set; } public string Item { get; set; } = string.Empty; }

Lambda 関数が、Stream オブジェクト以外の入出力タイプを使用する場合は、アプリケーションにシリアル化ライブラリを追加する必要があります。これにより、JSON 入力を定義したクラスのインスタンスに変換できます。Lambda の C# 関数のシリアル化には、リフレクションベースのシリアル化とソース生成のシリアル化の 2 つの方法があります。

リフレクションベースのシリアル化

AWS は、アプリケーションに迅速に追加できる事前構築済みライブラリを提供しています。これらのライブラリは、リフレクションを使用してシリアル化を実装します。リフレクションベースのシリアル化を実装するには、次のいずれか 1 つのパッケージを使用します。

  • Amazon.Lambda.Serialization.SystemTextJson – バックエンドでは、このパッケージは System.Text.Json を使用してシリアル化タスクを実行します。

  • Amazon.Lambda.Serialization.Json – バックエンドでは、このパッケージは Newtonsoft.Json を使用してシリアル化タスクを実行します。

ILambdaSerializer インターフェイスの実装によって独自のシリアル化ライブラリを作成することもできます。これは、Amazon.Lambda.Core ライブラリの一部として使用できます。このインターフェイスは 2 つのメソッドを定義します。

  • T Deserialize<T>(Stream requestStream);

    このメソッドを実装して、Invoke API から Lambda 関数ハンドラーに渡されるオブジェクトにリクエストのペイロードを逆シリアル化することができます。

  • T Serialize<T>(T response, Stream responseStream);

    このメソッドを実装して、Lambda 関数のハンドラーから返される結果を Invoke API オペレーションが返すレスポンスペイロードにシリアル化することができます。

このページのメインの例では、リフレクションベースのシリアル化を使用しています。リフレクションベースのシリアル化は、AWS Lambda ですぐに機能し、追加のセットアップを必要としないため、作業をシンプルにするにはよい選択です。ただし、関数のメモリ使用量を増やす必要があります。ランタイムリフレクションにより、関数のレイテンシーが高くなる場合もあります。

ソース生成のシリアル化

ソース生成のシリアル化では、コンパイル時にシリアル化コードが生成されます。これにより、リフレクションが不要になり、関数のパフォーマンスが向上します。ソース生成のシリアル化を関数で使用するには、以下を実行する必要があります。

  • JsonSerializerContext を継承する新しい部分クラスを作成し、シリアル化または逆シリアル化を必要とするすべての型の JsonSerializable 属性を追加します。

  • LambdaSerializer を設定して SourceGeneratorLambdaJsonSerializer<T> を使用します。

  • アプリケーションコード内の手動シリアル化および逆シリアル化をすべて更新して、新しく作成したクラスを使用するようにします。

次の例は、リフレクションベースのシリアル化を使用するこのページのメインの例を変更して、代わりにソース生成のシリアル化を使用する方法を示しています。

using System.Text.Json; using System.Text.Json.Serialization; ... public class Order { public string OrderId { get; set; } = string.Empty; public double Amount { get; set; } public string Item { get; set; } = string.Empty; } [JsonSerializable(typeof(Order))] public partial class OrderJsonContext : JsonSerializerContext {} public class OrderHandler { ... public async Task<string> HandleRequest(string input, ILambdaContext context) { var order = JsonSerializer.Deserialize(input, OrderJsonContext.Default.Order); ... } }

ソース生成のシリアル化には、リフレクションベースのシリアル化よりも多くのセットアップが必要です。ただし、ソース生成を使用する関数は、コンパイル時のコード生成により、メモリ使用量が減少し、パフォーマンスが向上します。関数のコールドスタートを排除するには、ソース生成のシリアル化に切り替えることを検討してください。

注記

Lambda でネイティブの事前コンパイル (AOT) を使用する場合は、ソース生成のシリアル化を使用する必要があります。

Lambda コンテキストオブジェクトへのアクセスと使用

Lambda コンテキストオブジェクトには、呼び出し、関数、および実行環境に関する情報が含まれます。この例では、コンテキストオブジェクトは Amazon.Lambda.Core.ILambdaContext 型で、メインハンドラー関数の 2 番目の引数です。

public async Task<string> HandleRequest(Order order, ILambdaContext context) { ... }

コンテキストオブジェクトはオプションの入力です。有効な受理されたハンドラー署名の詳細については、「C# 関数の有効なハンドラー署名」を参照してください。

コンテキストオブジェクトは、Amazon CloudWatch に関数ログを生成するのに役立ちます。context.getLogger() メソッドを使用して、ログ記録用の LambdaLogger オブジェクトを取得できます。この例では、何らかの理由で処理が失敗した場合、ロガーを使用してエラーメッセージをログに記録できます。

context.Logger.LogError($"Failed to process order: {ex.Message}");

ログ記録以外では、関数のモニタリングにコンテキストオブジェクトを使用することもできます。コンテキストオブジェクトの詳細については、「Lambda コンテキストオブジェクトを使用して C# 関数の情報を取得する」を参照してください。

ハンドラーでの SDK for .NET v3 の使用

多くの場合、Lambda 関数を使用して、他の AWS リソースとやり取りしたり、更新したりします。これらのリソースとインターフェイスする最も簡単な方法は、SDK for .NET v3 を使用することです。

注記

SDK for .NET (v2) は非推奨になりました。今後は SDK for .NET v3 のみを使用することをお勧めします。

次の Amazon.Lambda.Tools コマンドを使用して、プロジェクトに SDK 依存関係を追加できます。

dotnet add package <package_name>

例えば、このページのメインの例では、Amazon S3 API を使用して S3 に受信をアップロードする必要があります。次のコマンドを使用して、Amazon S3 SDK クライアントをインポートできます。

dotnet add package AWSSDK.S3

このコマンドは、依存関係をプロジェクトに追加します。また、プロジェクトの .csproj ファイルには次のような行が表示されます。

<PackageReference Include="AWSSDK.S3" Version="3.7.2.18" />

次に、依存関係を C# コードに直接インポートします。

using Amazon.S3; using Amazon.S3.Model;

その後、コード例では、Amazon S3 クライアントを (デフォルトの認証情報プロバイダーチェーンを使用して) 次のように初期化します。

private static readonly AmazonS3Client s3Client = new();

この例では、関数を呼び出すたびに Amazon S3 クライアントを初期化する必要がないように、メインハンドラー関数の外で Amazon S3 クライアントを初期化しました。SDK クライアントを初期化したら、SDK クライアントを使用して他の AWS サービスとやり取りできます。サンプルコードは、以下のように Amazon S3 PutObject API を呼び出します。

var putRequest = new PutObjectRequest { BucketName = bucketName, Key = key, ContentBody = receiptContent, ContentType = "text/plain" }; await s3Client.PutObjectAsync(putRequest);

環境変数にアクセスする

ハンドラーコードでは、System.Environment.GetEnvironmentVariable メソッドを使用して任意の環境変数を参照できます。この例では、以下のコード行を使用して、定義された RECEIPT_BUCKET 環境変数を参照します:

string? bucketName = Environment.GetEnvironmentVariable("RECEIPT_BUCKET"); if (string.IsNullOrWhiteSpace(bucketName)) { throw new ArgumentException("RECEIPT_BUCKET environment variable is not set"); }

グローバルな状態を使用する

Lambda は、関数を初めて呼び出す前の初期化フェーズで静的コードとクラスコンストラクターを実行します。初期化中に作成されたリソースは呼び出し間でメモリに保持されるため、関数を呼び出すたびにリソースを作成する必要がなくなります。

コード例では、S3 クライアント初期化コードはメインハンドラーメソッドの外にあります。ランタイムは、関数が最初のイベントを処理する前にクライアントを初期化するため、処理時間が長くなる可能性があります。Lambda がクライアントを再度初期化する必要がないため、後続のイベントはより高速になります。

Lambda Annotations Framework による関数コードの簡略化

Lambda Annotations は .NET 8 用のフレームワークであり、C# を使用して Lambda 関数の記述を簡素化します。Annotations Framework はソースジェネレーターを使用して、Lambda プログラミングモデルから簡素化されたコードに変換するコードを生成します。Annotations Framework では、通常のプログラミングモデルを使用して記述された Lambda 関数のコードの多くを置き換えることができます。このフレームワークを使用して記述されたコードでは、ビジネスロジックに集中できるより単純な式が使用されます。例については、nuget ドキュメントの「Amazon.Lambda.Annotations」を参照してください。

Lambda Annotations を利用する完全なアプリケーションの例については、awsdocs/aws-doc-sdk-examplesGitHub リポジトリの PhotoAssetManager の例を参照してください。Function.cs ディレクトリのメイン PamApiAnnotations ファイルで Lambda Annotations が使用されています。比較のために、PamApi ディレクトリには、通常の Lambda プログラミングモデルを使用して記述された同等のファイルがあります。

Lambda Annotations Framework による依存関係インジェクション

Lambda Annotations Framework を使用して、使い慣れた構文を用いて Lambda 関数に依存関係インジェクションを追加することもできます。[LambdaStartup] 属性を Startup.cs ファイルに追加すると、Lambda Annotations Framework がコンパイル時に必要なコードを生成します。

[LambdaStartup] public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton<IDatabaseRepository, DatabaseRepository>(); } }

Lambda 関数は、コンストラクタインジェクションを使用するか、[FromServices] 属性を使用して個々のメソッドに挿入することで、サービスを挿入できます。

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] namespace GetProductHandler; public class Function { private readonly IDatabaseRepository _repo; public Function(IDatabaseRepository repo) { this._repo = repo; } [LambdaFunction] [HttpApi(LambdaHttpMethod.Get, "/product/{id}")] public async Task<Product> FunctionHandler([FromServices] IDatabaseRepository repository, string id) { return await this._repo.GetById(id); } }

C# Lambda 関数のコードのベストプラクティス

Lambda 関数をビルドするときは、次のリストのガイドラインに従って、コーディングのベストプラクティスを実行してください。

  • Lambda ハンドラーをコアロジックから分離します。これにより、関数の単体テストが実行しやすくなります。

  • 関数のデプロイパッケージ内で依存関係を制御します。AWS Lambda 実行環境には多数のライブラリが含まれています。最新の機能やセキュリティ更新プログラムを有効にするために、Lambda はこれらのライブラリを定期的に更新します。この更新により、Lambda 関数の動作が微妙に変化する場合があります。関数で使用する依存関係を完全に制御するには、すべての依存関係をデプロイパッケージでパッケージングします。

  • 依存関係の複雑さを最小限に抑えます。フレームワークを単純化して、実行環境起動時のロードを高速化します。

  • デプロイパッケージをランタイムに必要な最小限のサイズにします。これにより、呼び出しに先立ってデプロイパッケージをダウンロードして解凍する所要時間が短縮されます。.NET で記述された関数の場合は、デプロイパッケージの一部として AWS SDK ライブラリ全体をアップロードしないようにします。代わりに、SDK のコンポーネントを必要に応じて選別するモジュール (DynamoDB、Amazon S3 SDK モジュール、Lambda コアライブラリなど) を使用します。

  • 実行環境の再利用を活用して関数のパフォーマンスを向上させます。関数ハンドラー外で SDK クライアントとデータベース接続を初期化し、静的なアセットを /tmp ディレクトリにローカルにキャッシュします。関数の同じインスタンスで処理された後続の呼び出しは、これらのリソースを再利用できます。これにより、関数の実行時間が短縮され、コストが節約されます。

    呼び出し間でデータが漏れるのを防ぐため、実行環境を使用してセキュリティ上の懸念があるユーザーデータ、イベント、またはその他の情報を保存しないでください。関数がハンドラー内のメモリに保存できない変更可能な状態に依存している場合は、ユーザーごとに個別の関数または個別のバージョンの関数を作成することを検討してください。

  • keep-alive ディレクティブを使用して永続的な接続を維持します。Lambda は、時間の経過とともにアイドル状態の接続を消去します。関数を呼び出すときにアイドル状態の接続を再利用しようとすると、接続エラーが発生します。永続的な接続を維持するには、ランタイムに関連付けられている keep-alive ディレクティブを使用します。例については、「Node.js で Keep-alive を使用して接続を再利用する」を参照してください。

  • 環境変数を使用して、オペレーショナルパラメータを関数に渡します。たとえば、Amazon S3 バケットに書き込む場合、書き込み先のバケット名はハードコーディングせずに、環境変数として設定します。

  • Lambda 関数では、再帰呼び出しを使用しないでください。関数が自身を呼び出すこともあれば、新たに開始されたプロセスで関数が再度呼び出される可能性もあります。これを行うと意図しないボリュームで関数が呼び出され、料金が急増する可能性があります。意図しない呼び出しがいくつも見つかった場合は、すぐに関数の予約済同時実行数を 0 に設定して、コードを更新している間のすべての関数の呼び出しをスロットリングします。

  • Lambda 関数コードで文書化されていない非公開の API を使用しないでください。AWS Lambda マネージドランタイムでは、Lambda が Lambda の内部 API にセキュリティと機能面の更新を定期的に適用します。これらの内部 API 更新には後方互換性がないことがあり、関数にこれらの非公開 API に対する依存関係がある場合、呼び出しの失敗などの意図しない結果につながります。公開されている API のリストについては、「API リファレンス」を参照してください。

  • 冪等性コードを記述します。関数の記述に冪等性コードを使用すると、重複するイベントが同じ方法で処理されるようになります。コードでは、イベントを適切に検証し、重複するイベントを適切に処理する必要があります。詳細については、「Lambda 関数を冪等にするにはどうすればよいですか?」を参照してください。

プライバシーサイト規約Cookie の設定
© 2025, Amazon Web Services, Inc. or its affiliates.All rights reserved.