Java の AWS Lambda 関数ハンドラー
Lambda 関数のハンドラーは、イベントを処理する関数コード内のメソッドです。関数が呼び出されると、Lambda はハンドラーメソッドを実行します。ハンドラーによってレスポンスが終了するか、レスポンスが返ったら、別のイベントを処理できるようになります。
以下の例では、Handler
という名前のクラスで handleRequest
という名前のハンドラーメソッドを定義しています。ハンドラーメソッドは、イベントとコンテキストオブジェクトを入力として受け取り、文字列を返します。
例 Handler.java
package example; import com.amazonaws.services.lambda.runtime.Context import com.amazonaws.services.lambda.runtime.RequestHandler import com.amazonaws.services.lambda.runtime.LambdaLogger ... // Handler value: example.Handler public class Handler implements RequestHandler<Map<String,String>, String>{ Gson gson = new GsonBuilder().setPrettyPrinting().create(); @Override
public String handleRequest(Map<String,String> event, Context context)
{ LambdaLogger logger = context.getLogger(); String response = new String("200 OK"); // log execution details logger.log("ENVIRONMENT VARIABLES: " + gson.toJson(System.getenv())); logger.log("CONTEXT: " + gson.toJson(context)); // process event logger.log("EVENT: " + gson.toJson(event)); logger.log("EVENT TYPE: " + event.getClass().toString()); return response; } }
Lambda ランタイムは、イベントを JSON 形式の文字列として受け取り、オブジェクトに変換します。また、イベントオブジェクトを、呼び出しと関数の詳細を提供するコンテキストオブジェクトと共に、関数ハンドラーに渡します。関数の設定でハンドラーパラメータを指定することで、呼び出すメソッドをランタイムに指示します。
ハンドラーの形式
-
- 完全形式。例:package
.Class
::method
example.Handler::handleRequest
。 -
- ハンドラーインターフェイスを実装する関数の省略形式。例:package
.Class
example.Handler
。
ハンドラーメソッドの外側に初期化コードを追加して、複数の呼び出し間でリソースを再利用できます。ランタイムがハンドラーをロードすると、静的コードとクラスコンストラクタが実行されます。初期化中に作成されたリソースは、呼び出し間でメモリ内に留まり、ハンドラーによって何千回も再利用できます。
以下の例では、関数が最初のイベントを処理するときに、ロガー、シリアライザーが作成されます。同じ関数インスタンスによって処理される後続のイベントは、それらのリソースが既に存在するため、はるかに高速です。
例 HandlerS3.java - 初期化コード
public class HandlerS3 implements RequestHandler<S3Event, String>{
private static final Logger logger = LoggerFactory.getLogger(HandlerS3.class); Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Override public String handleRequest(S3Event event, Context context) { ... }
このガイドの GitHub リポジトリには、さまざまなハンドラータイプを示す、簡単にデプロイできるサンプルアプリケーションが用意されています。詳細については、このトピックの最後を参照してください。
入力タイプと出力タイプの選択
イベントがマッピングするオブジェクトのタイプは、ハンドラーメソッドの署名で指定します。上記の例では、Java ランタイムはイベントを、Map<String,String>
インターフェイスを実装するタイプに逆シリアル化します。文字列から文字列へのマッピングは、以下のような階層なしのイベントで機能します。
例 Event.json - 気象データ
{ "temperatureK": 281, "windKmh": -3, "humidityPct": 0.55, "pressureHPa": 1020 }
ただし、各フィールドの値は文字列または数値であることが必要です。イベント内のフィールドにオブジェクトが値として含まれている場合、ランタイムはそれを逆シリアル化できず、エラーを返します。
関数が処理するイベントデータに使用する入力タイプを選択します。基本タイプ、汎用タイプ、または良定義タイプを使用できます。
入力タイプ
-
Integer
Long
、Double
、など - イベントは、追加の形式のない数値です (3.5
など)。ランタイムは、値を指定されたタイプのオブジェクトに変換します。 -
String
- イベントは、引用符を含む JSON 文字列です ("My string."
など)。ランタイムは、引用符なしの値をString
オブジェクトに変換します。 -
、Type
Map<String,
など - イベントは JSON オブジェクトです。ランタイムは、それを指定されたタイプまたはインターフェイスのオブジェクトに逆シリアル化します。Type
> -
List<Integer>
List<String>
、List<Object>
、など - イベントは JSON 配列です。ランタイムは、それを指定されたタイプまたはインターフェイスのオブジェクトに逆シリアル化します。 -
InputStream
- イベントは任意の JSON タイプです。ランタイムは、ドキュメントのバイトストリームを変更せずにハンドラーに渡します。入力を逆シリアル化し、出力を出力ストリームに書き込みます。 -
ライブラリタイプ - AWS サービスによって送信されるイベントの場合、aws-lambda-java-events ライブラリのタイプを使用します。
独自の入力タイプを定義する場合、そのタイプは、逆シリアライズかつ変更可能な Plain Old Java Object (POJO) であり、デフォルトのコンストラクタと、イベントの各フィールドのプロパティが必要です。プロパティにマッピングされないイベントのキー、およびイベントに含まれていないプロパティは、エラーなしでドロップされます。
出力タイプはオブジェクトまたは void
です。ランタイムは、戻り値をテキストにシリアル化します。出力が、フィールドを含むオブジェクトの場合、ランタイムは、それを JSON ドキュメントにシリアル化します。出力が、プリミティブ値をラップするタイプの場合、ランタイムは、その値のテキスト表現を返します。
ハンドラーのインターフェイス
aws-lambda-java-core
RequestHandler
インターフェイスは、入力タイプと出力タイプの 2 つのパラメータを受け取る汎用タイプです。どちらのタイプもオブジェクトであることが必要です。このインターフェイスを使用すると、Java ランタイムはイベントを入力タイプのオブジェクトに逆シリアル化し、出力をテキストにシリアル化します。組み込みのシリアル化が入力タイプと出力タイプで機能する場合は、このインターフェイスを使用します。
例 Handler.java - ハンドラーインターフェイス
// Handler value: example.Handler public class Handler implements RequestHandler<Map<String,String>, String>{ @Override
public String handleRequest(Map<String,String> event, Context context)
独自のシリアル化を使用するには、RequestStreamHandler
インターフェイスを実装します。このインターフェイスでは、Lambda はハンドラーに入力ストリームと出力ストリームを渡します。ハンドラーは、入力ストリームからバイトを読み取り、出力ストリームに書き込み、void を返します。
以下の例では、バッファされたリーダーとライターのタイプを使用して、入力ストリームと出力ストリームを処理しています。シリアル化と逆シリアル化には Gson
例 ハンドラーストリーム
import com.amazonaws.services.lambda.runtime.Context import com.amazonaws.services.lambda.runtime.RequestStreamHandler import com.amazonaws.services.lambda.runtime.LambdaLogger ... // Handler value: example.HandlerStream
public class HandlerStream implements RequestStreamHandler
{ Gson gson = new GsonBuilder().setPrettyPrinting().create(); @Overridepublic void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException
{ LambdaLogger logger = context.getLogger(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("US-ASCII"))); PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, Charset.forName("US-ASCII")))); try { HashMap event = gson.fromJson(reader, HashMap.class); logger.log("STREAM TYPE: " + inputStream.getClass().toString()); logger.log("EVENT TYPE: " + event.getClass().toString()); writer.write(gson.toJson(event)); if (writer.checkError()) { logger.log("WARNING: Writer encountered an error."); } } catch (IllegalStateException | JsonSyntaxException exception) { logger.log(exception.toString()); } finally { reader.close(); writer.close(); } } }
サンプルハンドラーコード
このガイドの GitHub リポジトリには、さまざまなハンドラータイプとインターフェイスの使用方法を示すサンプルアプリケーションが含まれています。各サンプルアプリケーションには、簡易のデプロイとクリーンアップ用のスクリプト、AWS SAM テンプレート、サポートリソースが含まれています。
Java のサンプル Lambda アプリケーション
-
java-basic
- 単位テストと変数ログ記録設定を使用する、最小限の Java 関数のコレクション。 -
java-events
- Amazon API Gateway、Amazon SQS、Amazon Kinesis などのさまざまなサービスからのイベントを処理する方法のスケルトンコードを含む Java 関数のコレクション。これらの関数は、最新バージョンの aws-lambda-java-events ライブラリ (3.0.0 以降) を使用します。これらの例では、依存関係としての AWS SDK が不要です。 -
s3-java
- Amazon S3 からの通知イベントを処理し、Java Class Library (JCL) を使用して、アップロードされたイメージファイルからサムネイルを作成する Java 関数。 -
API ゲートウェイを使用して Lambda 関数を呼び出す - 従業員情報を含む Amazon DynamoDB テーブルをスキャンする Java 関数。次に、Amazon Simple Notification Service を使用して、仕事の記念日を祝うテキストメッセージを従業員に送信します。この例では、API ゲートウェイを使用して関数を呼び出します。
java-events
および s3-java
アプリケーションは、AWS サービスのイベントを入力として受け取り、文字列を返します。java-basic
アプリケーションには数タイプのハンドラーが含まれています。
-
Handler.java
- Map<String,String>
を入力として受け取ります。 -
HandlerInteger.java
- Integer
を入力として受け取ります。 -
HandlerList.java
- List<Integer>
を入力として受け取ります。 -
HandlerStream.java
- InputStream
とOutputStream
を入力として受け取ります。 -
HandlerString.java
- String
を入力として受け取ります。 -
HandlerWeatherData.java
- カスタムタイプを入力として受け取ります。
さまざまなハンドラータイプをテストするには、AWS SAM テンプレートのハンドラー値を変更するだけです。詳細な手順については、サンプルアプリケーションの readme ファイルを参照してください。