Amazon API Gateway + Lambda統合をJavaで実装するメモ 

## 対象読者
 - 自分
 - JavaでLambdaを実装する人
## API Gateway
REST APIで定義する。
メソッドの作成時、統合タイプが選択できる。この時Lambda関数が選択できるが、
 - 「Lambda プロキシ統合の使用」にチェックを入れるとLambdaプロキシ統合のリクエスト・レスポンス形式に沿ってLambda（Java）の実装が必要
    - Lambda プロキシ統合
 - チェックを入れないとAPI Gateway側の「統合リクエスト - マッピングテンプレート」での定義が必要となる。
    - API Gateway 内でリクエスト変換をするということ
    - Lambda 非プロキシ統合

マッピングテンプレートの例：
 ```text:マッピングテンプレート
#set($inputRoot = $input.path('$'))
{
  "title" : $input.json('$.title'),
  "body" : $input.json('$.body'),
  "coverImageUrl" : $input.json('$.coverImageUrl'),
  "backgroundImageUrl" : $input.json('$.backgroundImageUrl')
}

```

 ## LambdaのrequestHandleメソッドの実装

Lambda 非プロキシ統合の場合：
```java
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の「モデル」からモデルのスキーマを定義する。
```text:モデルのスキーマ
{
  "$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で良い。

```java
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 プロキシ統合の場合：
```java:ハンドラの例
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から提供されているのでそれを使う。
[この辺り](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/java-events)
```xml: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