AWS Lambdaの開発 私のベストプラクティス

JavaのWebアプリケーション開発（JavaEE）をメインスキルとする私が考えるAWS Lambda開発のベストプラクティスと、開発環境の構築に関するTipsを書いてみます。

JavaEEの資格持ちなので、そこそこのプログラミングスキルはあるつもりですが、AWS Lambda歴は1ヵ月程度です。
java以外の言語については「リファレンスを読めばそれっぽく書けますよ」というレベルです。

#サービス構成
実現するアプリケーション次第だと思いますが、私はAPI Gateway + Lambda + DynamoDB のserverlessアーキテクチャをチョイスしました。
サーバーのお世話をしなくて良いという、誘惑にのってみました。

ソースコード管理についてはCodeCommit(git)を利用し、AWSでまとめます。


#言語の選択
AWS Lambdaで利用できる言語としては2017年5月時点でC#、Node.js(JavaScript)、Java、Pythonです。
尚、バージョンの差異は言語仕様的にそれほど大きな違いでは無い認識のため、選択肢に含めていません。

選択の基準としては、開発の生産性とデプロイのし易さを基準にします。（私見です）

- 先にデプロイの話から
 
C#とJavaについてはバイナリファイルをZip(Javaの場合はjarもあり)で固めてアップロードするかS3に置きます。
Node.jsとPythonについては上記に加えmanagement consoleから直接編集が出来ます。
（言語がインタプリンタだから出来る事ですね）
ただし、Node.jsもPythonもモジュール化（ファイル分割）をした場合はZipで固めてアップロードすることになります。

コーディングしたものをすぐに動作確認できるお手軽さでNode.jsとPythonが優位だと思います。

- 生産性

Java屋さんの私にとってNode.jsの非同期処理は学習コストがかかりました。
コーディングを始めて早々、callback地獄にはまってしまい、ビジネスロジックをモリモリと書き進めることが出来ません。
関数内の処理結果を戻り値として返し、呼び出し側の処理を継続するという単純な処理が簡素に書けず、非常にストレスでした。

という事で1ヵ月使った結果、生産性とデプロイの面で良かった言語はPythonです。

#統合開発環境（IDE）

Java屋さんの私にはEclipse一択

いつもお世話になっているPleiadesのサイトにPython向けのPluginを導入したパッケージがあるので、こちらを利用します。
IDEを利用するとインタプリンタ言語でも構文チェックをしてくれたり、IDEからプログラムが実行出来るのは便利ですね。

また、EclipseであればAWS Toolkit for Eclipse が利用できます。
CodeCommitについてもEclipseのEGitから利用できますので、別のツール類をそろえる手間が省けます。

# ローカルの実行環境
AWSの無料枠内で利用すれば気にすることはありません、ローカル実行環境を作って気兼ねなく開発するのもありだと思います。

環境構築としては以下の作業になります。

~~- Pleiades(Python向け)インストール~~
~~⇒ ここからインストール (http://mergedoc.osdn.jp/)~~

~~- AWS Toolkit for Eclipseの導入~~
~~⇒ 参考(http://docs.aws.amazon.com/ja_jp/toolkit-for-eclipse/v1/user-guide/setup-install.html)~~

上記の Eclipse、AWS Toolkit for Eclipseのインストール手順について訂正します。
Python向けにカスタマイズされたPleiadesを利用するとJDT(Eclipse Java development tools)が無いため、AWS Toolkit for Eclipseの主要なPluginがインストールできません。

実際に私が行った手順は以下になります。

- Pleiades(Eclipse 4.6 Neon 3 Java向け)インストール
  ⇒ ここからインストール (http://mergedoc.osdn.jp/)

- AWS Toolkit for Eclipseの導入
  ⇒ 参考(http://docs.aws.amazon.com/ja_jp/toolkit-for-eclipse/v1/user-guide/setup-install.html)
     ※AWS Android Developmentは依存関係が解決できずインストールが進まなくなるため、インストール対象に含めない

- Pydevインストール
  ⇒ Eclipse マーケットプレースからPydevをインストール
- Windows版Python 3.6インストール
  ⇒ ここからインストール (https://www.python.org/)
- pipでboto3のインストール
  ⇒Pythonのインストールディレクトリ配下にあるpip.exeを利用する。
以下のコマンドをDOSプロンプトから実行

    ```
    >pip install boto3
    ```

install したboto3は実行時に参照できるよう、Pathを通しておきます。
![python path.png](https://qiita-image-store.s3.amazonaws.com/0/169729/f1f94dd8-c871-908f-0f12-2b76e088b6a8.png)


- DynamoDB Localの導入
AWS Toolkit for Eclipseを導入したEclipseから「ウィンドウ」→「設定」を選択
DynamoDB ローカル・テスト・ツールからインストール
![dynamodb local.png](https://qiita-image-store.s3.amazonaws.com/0/169729/1dc54097-ca93-e88f-6e28-24eb86ccea6a.png)


注意点としてはDynamoDB Localはregionがus-east-1固定のようなので、プログラム側のdynamodb接続先を合わせておく必要があります。

us-east-1固定というのはテーブルを作ってみるとファイル名にRegionが付与されるのでわかります。
![us-east-1.png](https://qiita-image-store.s3.amazonaws.com/0/169729/01b7f87d-1893-2877-ae68-da629b347c61.png)




~~という訳でソースコードをローカル環境用に修正します。~~
~~※ここはAWS環境に置く時に問題になるので、何とかしたいです。~~
これは環境変数の利用で解決しました。（wukannさんコメントありがとうございます）

```py:env.py
# 環境依存する設定を記述するファイル
import os
import boto3

if os.environ.get('EXEC_ENV') == 'TEST':
    # DynamoDB Local用の接続はportを変えておく
    print('Environment is TEST')
    dynamodb = boto3.resource('dynamodb', region_name='us-east-1', endpoint_url="http://localhost:8001")
else:
    # AWS 上で動作する際の接続
    dynamodb = boto3.resource('dynamodb')
```

あとは AWS Lambda Functionを動かす為のdriverを作りますが、API Gatewayからの入力がJSON形式になるため、入力パラメータをJSON形式で渡すdriverを書きます。

```py:handlerのdriver

# DynamoDBの接続を帰るため、環境変数に'TEST'を設定
import os
os.environ['EXEC_ENV'] = 'TEST'

# 被テスト function
from xxx_function import xxx_function_handler

if __name__ == '__main__':
    event = {
        "body": "{\"param1\":\"aaaa\",\"param2\":\"bbbb\",\"param3\":\"cccc\"}"
    }
    result = xxx_function_handler(event ,None)

    logger.debug('result{}'.format(result))

```


これで開発環境とUnitテストまでをローカルで実施できる実行環境の出来上がりです。