MacでAWS Lambda関数(java)を作るまで

# MacでAWS Lambda関数(java)を作るまで

思いつきで使った事のないMacBookAirを買い、思いつきでAWS Lambda関数を作ろうとしたものの、慣れないJavaScriptで書くのはストレスなので、慣れたJavaで作ろうとしたところ、すんなりといかなかったので残しておきます。


## 前提
* 2019.08.03現在のAWS Lambdaのランタイムは、ava-1.8.0-openjdk-Amazon linuxです
* [homebrew](https://brew.sh/index_ja.html)というものがインストールされていること
* [anyenv](https://github.com/anyenv/anyenv)というものがインストールされていること

## javaのインストール
#### java8の検索
Macにjavaをインストールします。lambdaランタイムがopenjdk8なのでhomebrewでopenjdkがインストールできるのか探します。

```bash
# おまじない
$ brew tap caskroom/versions
# openjdkを検索
$ brew search openjdk
==> Casks
adoptopenjdk                             adoptopenjdk8
```
#### openjdkのインストール
「adoptopenjdk8」という、いかにもjava8らしきものがあったのでこれをインストールします。途中でパスワードを聞かれますのでOSのパスワードを入力します。

```bash
# openjdk ver8をinstall
$ brew cask install adoptopenjdk8
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
No changes to formulae.

==> Satisfying dependencies
==> Downloading https://github.com/AdoptOpenJDK/openjdk8-binaries/releases/downl
==> Downloading from https://github-production-release-asset-2e65be.s3.amazonaws
######################################################################## 100.0%
==> Verifying SHA-256 checksum for Cask 'adoptopenjdk8'.
==> Installing Cask adoptopenjdk8
==> Running installer for adoptopenjdk8; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are i
Password: #osのパスワード入力
installer: Package name is AdoptOpenJDK
installer: Installing at base path /
installer: The install was successful.
🍺  adoptopenjdk8 was successfully installed!
```
#### javaバージョンの確認
macで有効になっているjavaバージョンを確認してみます。

```bash
$ java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_222-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.222-b10, mixed mode)
```

#### jenvのインストール
[jenv](https://github.com/jenv/jenv#readme)はjavaのバージョンをフォルダ毎に指定したりとかいい感じにやってくれるものです。
ReadMeに沿ってインストールします。

```bash
$ anyenv install jenv
```

#### jenvにJavaを追加する
jenv経由でjavaをインストールできないので、インストールされたjavaをjenvに教えてあげる必要があります。

```bash
$ jenv add $(/usr/libexec/java_home)
openjdk64-1.8.0.222 added
1.8.0.222 added
1.8 added
```

#### javaバージョンの確認
jenvが扱えるjavaバージョンの確認

```bash
$ jenv versions
* system (set by /Users/xxx/.anyenv/envs/jenv/version)
  1.8
  1.8.0.222
  openjdk64-1.8.0.222
```
## Mavenのインストール
ライブラリの定義やビルドをしやすくしたいのでMavenも入れます。

#### Mavenの検索
Mavenもhomebrewで入れられました。

```bash
$ brew search maven
==> Formulae
maven   maven-completion   maven-shell   maven@3.2   maven@3.3   maven@3.5

==> Casks
mavensmate   homebrew/cask-fonts/font-maven-pro
```
#### Mavenのインストール
特にバージョンにはこだわらないので最新をインストール。

```bash
$ brew install maven
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/cask and caskroom/versions).
No changes to formulae.

==> Downloading https://www.apache.org/dyn/closer.cgi?path=maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
==> Downloading from https://www-eu.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
######################################################################## 100.0%
🍺  /usr/local/Cellar/maven/3.6.1: 79 files, 10.2MB, built in 30 seconds
```

## Visual Studio Codeの設定
Eclipseでも良いのですが、軽いと噂のVisual Studio Codeを使ってみたいのでインストール。

#### Visual Studio Codeのインストール
[Download Visual Studio Code](https://code.visualstudio.com/download)からダウンロードしてインストールしてください。

#### VS CodeにJavaの拡張機能を追加
こちらに纏まっていますので、こちらを参照して「Java Extension Pack」の追加を行って下さい。
[「java開発環境をvisual-studio-code-で整える」](https://solutionware.jp/blog/2018/06/01/java開発環境をvisual-studio-code-で整える/)
※jenvのおかげかJAVA_HOMEの設定はせずとも大丈夫でした。

## Javaの実装 & AWS Lambda関数にデプロイ
こちらに丁寧に纏まっていますので、こちらを参照して下さい。
[「いまからはじめるJavaでAWS Lambda(ラムダ) 前編」](https://qiita.com/riversun/items/7fcc06617b469aed8f27)

## AWS API Gateway
パブリックに呼び出せるように、AWS LambdaのトリガーをAPI Gatewayにします。
が、ここで大ハマりしました。
上記までで、AWS Lambdaのテストはうまくいくのですが、API Gatewayを作ってテストを実行すると502でエラーとなるのです。

結論から言うと「API Gateway」の「統合リクエスト」の設定が初期値だとうまくいきませんでした。

#### AWS Lambdaにトリガーを設定
ここは素直に「＋」ボタンでトリガーを追加して、下記のように選択します。

1. API Gateway を選択
2. API：素直に「新しいAPIを作成」
3. セキュリティ：後からでも変更できるので、テストのしやすさを考えて「オープン」

<img width="1064" alt="スクリーンショット 2019-08-04 18.24.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393858/a62d9b72-f254-7378-2cc0-740ab4e95f56.png">

<img width="853" alt="スクリーンショット 2019-08-04 18.47.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393858/781fd58b-9365-3aca-8749-c64dca305c0c.png">

#### 統合リクエストの設定を変える
AWS Lambda コンソールにて、追加れたメソッドの「統合リクエスト」を選択します。

<img width="1049" alt="スクリーンショット 2019-08-04 18.50.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393858/a5c6ff65-eef4-a8f3-11dc-89eb6946599e.png">

ここが大切です。
この中の「Lambdaプロキシ統合の使用」にチェックが入っているので、このチェックを外します。

<img width="1092" alt="スクリーンショット 2019-08-04 18.28.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393858/eb91f5c1-27c8-0ba0-341d-b4c123c1baed.png">

怖いインフォメーションも無視してOKを押します。
<img width="601" alt="スクリーンショット 2019-08-04 18.51.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393858/39ba3937-2974-4594-a791-29c4625a6c4d.png">

このチェックを外す事で、うまくいくようになりました。

#### まとめ
API GatewayからLambdaのJava を呼び出すところで、リクエストBODYのjsonの内容をJavaの入力パラメータのPOJOに値を詰める処理が動くわけですが、「Lambdaプロキシ統合の使用」にチェックが入っているとどうもここがうまくいきません。

推測するに、API Gatewayでは、リクエストの情報と一緒にAWSのメタな情報もセットで持ち回っており、「Lambdaプロキシ統合の使用」にチェックが入っていると、メタな情報もLambdaに渡せる反面、Lambda側でもそのつもりで受け取る実装にしておかないとダメで、今回の実装はjsonの内容しか受け取るようにしていなかったので失敗していたようです。

「Lambdaプロキシ統合の使用」のチェックを外すとリクエストBODYのみLambdaに渡すようになり、POJOで受け取れるようになりました。