対象読者
- 自分
- JavaでLambdaを実装する人
API Gateway
REST APIで定義する。
メソッドの作成時、統合タイプが選択できる。この時Lambda関数が選択できるが、
- 「Lambda プロキシ統合の使用」にチェックを入れるとLambdaプロキシ統合のリクエスト・レスポンス形式に沿ってLambda(Java)の実装が必要
- Lambda プロキシ統合
- チェックを入れないとAPI Gateway側の「統合リクエスト - マッピングテンプレート」での定義が必要となる。
- API Gateway 内でリクエスト変換をするということ
- Lambda 非プロキシ統合
マッピングテンプレートの例:
マッピングテンプレート
#set($inputRoot = $input.path('$'))
{
"title" : $input.json('$.title'),
"body" : $input.json('$.body'),
"coverImageUrl" : $input.json('$.coverImageUrl'),
"backgroundImageUrl" : $input.json('$.backgroundImageUrl')
}
LambdaのrequestHandleメソッドの実装
Lambda 非プロキシ統合の場合:
package com.example;
import lombok.Data;
@Data
public class ReviewRequest {
private String title;
private String body;
private String coverImageUrl;
private String backgroundImageUrl;
}
このようにDTO的なものを用意→API Gatewayの「モデル」からモデルのスキーマを定義する。
モデルのスキーマ
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "ReviewRequest",
"type": "object",
"properties": {
"title": { "type": "string" },
"body": {"type": "string"},
"coverImageUrl": {"type": "string"},
"backgroundImageUrl": {"type": "string"}
}
}
ハンドラの実装時のジェネリクスタイプも上のDTOで良い。
public class ReviewHandler implements RequestHandler<ReviewRequest, ReviewRequest>{
@Override
public ReviewRequest handleRequest(ReviewRequest event, Context context)
{
event.setTitle(event.getTitle()+" にlambdaで追記");
event.setBody(event.getBody()+" にlambdaで追記");
event.setCoverImageUrl(event.getCoverImageUrl()+" にlambdaで追記");
event.setBackgroundImageUrl(event.getBackgroundImageUrl()+" にlambdaで追記");
ObjectMapper mapper = new ObjectMapper();
String json = "";
try {
json = mapper.writeValueAsString(event);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
LambdaLogger logger = context.getLogger();
// process event
logger.log("EVENT: " + json);
logger.log("EVENT TYPE: " + event.getClass().toString());
return event;
}
}
Lambda プロキシ統合の場合:
ハンドラの例
public class ReviewLambdaIntegratedHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent>{
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context)
{
String body = event.getBody();
ObjectMapper mapper = new ObjectMapper();
String eventString = "";
try {
eventString = mapper.writeValueAsString(event);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();
response.setIsBase64Encoded(false);
response.setStatusCode(200);
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
response.setHeaders(headers);
response.setBody("{\"test\": \"body\"}");
LambdaLogger logger = context.getLogger();
// process event
logger.log("event: " + eventString);
logger.log("body: " + body);
logger.log("EVENT TYPE: " + event.getClass().toString());
return response;
}
}
Lambdaプロキシ統合の形式がAWSから提供されているのでそれを使う。
この辺り
pom.xml
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>3.11.0</version>
</dependency>
APIキーについて
ヘッダでの認証をする場合:
この辺りに情報がある。使用量プランを作成し、そこにAPIキー(x-api-keyヘッダ)を紐づけるやり方でできる。
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-api-key-source.html