

# Ruby の Lambda 関数ハンドラーの定義
<a name="ruby-handler"></a>

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

**Topics**
+ [Ruby ハンドラーの基本](#ruby-handler-basics)
+ [Ruby Lambda 関数のベストプラクティスに従ってください。](#ruby-best-practices)

## Ruby ハンドラーの基本
<a name="ruby-handler-basics"></a>

次の例では、`function.rb` は、`handler` という名前のハンドラメソッドを定義します。ハンドラ関数は、2 つのオブジェクトを入力として識別し、JSON ドキュメントを返します。

**Example function.rb**  

```
require 'json'

def handler(event:, context:)
    { event: JSON.generate(event), context: JSON.generate(context.inspect) }
end
```

関数設定の `handler` 設定は、ハンドラーの場所を Lambda に伝えます。前述の例では、この設定の適切な値は **function.handler** です。ドットで区切られた 2 つの名前 (ファイルの名前とハンドラメソッドの名前) が含まれています。

また、クラス内のハンドラメソッドを定義することもできます。以下の例では、モジュール `LambdaFunctions` のクラス `Handler` の ハンドラメソッド `process` を定義します。

**Example source.rb**  

```
module LambdaFunctions
  class Handler
    def self.process(event:,context:)
      "Hello!"
    end
  end
end
```

この場合、ハンドラ設定は **source.LambdaFunctions::Handler.process** です。

ハンドラは、呼び出しイベントとコンテキストの 2 つのオブジェクトを受け入れます。このイベントは、呼び出し元が提供するペイロードを含む Ruby オブジェクトです。ペイロードが JSON ドキュメントの場合、イベントオブジェクトは Ruby ハッシュです。それ以外の場合は、文字列です。[コンテキストオブジェクト](ruby-context.md)には、呼び出し、関数、および実行関数に関する情報を示すメソッドおよびプロパティがあります。

関数ハンドラーは、Lambda 関数が呼び出されるたびに実行されます。ハンドラの外側の静的コードは、関数のインスタンスごとに 1 回実行されます。ハンドラで SDK クライアントやデータベース接続などのリソースが使用される場合、ハンドラメソッドは、ハンドラメソッドの外で作成して複数の呼び出しに再利用することができます。

関数の各インスタンスで複数の呼び出しイベントを処理することはできますが、処理されるのは一度に 1 つのイベントのみです。任意の時点でイベントを処理するインスタンス数は、関数の*同時実行数*です。Lambda の実行環境の詳細については、[Lambda 実行環境のライフサイクルの概要](lambda-runtime-environment.md) を参照してください。

## Ruby Lambda 関数のベストプラクティスに従ってください。
<a name="ruby-best-practices"></a>

Lambda 関数をビルドするときは、次のリストのガイドラインに従って、コーディングのベストプラクティスを実行してください。
+ **Lambda ハンドラーをコアロジックから分離します。**これにより、関数の単体テストが実行しやすくなります。例えば、Ruby では次のようになります。

  ```
  def lambda_handler(event:, context:)
      foo = event['foo']
      bar = event['bar']
      
      result = my_lambda_function(foo:, bar:)
  
  end
  
  def my_lambda_function(foo:, bar:)
      // MyLambdaFunction logic here
      
  end
  ```
+ **関数のデプロイパッケージ内で依存関係を制御します。**AWS Lambda 実行環境には多数のライブラリが含まれています。Ruby ランタイムの場合、これらには AWS SDK が含まれます。最新の機能やセキュリティ更新プログラムを有効にするために、Lambda はこれらのライブラリを定期的に更新します。この更新により、Lambda 関数の動作が微妙に変化する場合があります。関数で使用する依存関係を完全に制御するには、すべての依存関係をデプロイパッケージでパッケージングします。
+ **依存関係の複雑さを最小限に抑えます。**フレームワークを単純化して、[実行環境](lambda-runtime-environment.md)起動時のロードを高速化します。
+ **デプロイパッケージをランタイムに必要な最小限のサイズにします。**これにより、呼び出しに先立ってデプロイパッケージをダウンロードして解凍する所要時間が短縮されます。Ruby で作成した関数の場合は、デプロイパッケージの一環として AWS SDK ライブラリ全体をアップロードしないようにします。代わりに、SDK のコンポーネントを必要に応じて選別する gem (DynamoDB、Amazon S3 SDK gem) を使用します。

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

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

**keep-alive ディレクティブを使用して永続的な接続を維持します。**Lambda は、時間の経過とともにアイドル状態の接続を消去します。関数を呼び出すときにアイドル状態の接続を再利用しようとすると、接続エラーが発生します。永続的な接続を維持するには、ランタイムに関連付けられている keep-alive ディレクティブを使用します。例については、「[Node.js で Keep-alive を使用して接続を再利用する](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html)」を参照してください。

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

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

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

**冪等性コードを記述します。**関数の記述に冪等性コードを使用すると、重複するイベントが同じ方法で処理されるようになります。コードでは、イベントを適切に検証し、重複するイベントを適切に処理する必要があります。詳細については、「[Lambda 関数を冪等にするにはどうすればよいですか?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/)」を参照してください。