AWS SAM CLIでHttpApiのローカルエミュレートがサポートされたのでWSL2のDocker上で使ってみた

# はじめに
みなさんAWS SAM CLIを使用されていますでしょうか？
[AWS SAM CLI](https://github.com/aws/aws-sam-cli)と言えば今年の7月に[正式リリース](https://aws.amazon.com/jp/about-aws/whats-new/2020/07/announcing-aws-serverless-application-model-cli-generally-available-production-use/)されて間もありませんが、AWS Lambdaのローカルエミュレートから環境構築まで出来るAWS Lambdaを使う上で強力なツールです。

そんなAWS SAM CLIですが、本日(2020年10月30日)にリリースされた[v1.7.0](https://github.com/aws/aws-sam-cli/releases/tag/v1.7.0)で下図の様なHttpApiとLambdaを組み合わせた環境のローカルエミュレートが出来るようになりました。

![httpapi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276566/97c048fa-5a7e-640b-372e-f465e00bdb79.png)



# 以前からHttpApiのサポートはあった
実は以前からHttpApiのサポートはあり、なんと2019年12月5日にリリースされた[v0.37.0](https://github.com/aws/aws-sam-cli/releases/tag/v0.37.0)の段階でAWS上に構築する事が出来ていました。
[ドキュメント](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-resource-httpapi.html)も用意されており、環境構築するだけならば問題なく使用出来ていたのですがSAMの目玉機能であるローカルエミュレートは対象外でした。

# 動作確認
実際にHttpAPIのローカルエミュレートを動かしてみます。

### 動作環境
- Windows10 Pro
- WSL2 (Ubuntu20.04)
- Docker for windows 2.4.0
- VSCode 1.50.1
    - Remote Development v0.20.0 ※拡張機能 

### 開発コンテナ構築
ローカルにインストールしたくないためWSL2上のDocker内で完結するように構築します。
まず、WSL上の作業用フォルダ作成し、VSCodeで開きます。
powershellにてコマンドを入力します。


```powershell
wsl # WSLに切り替え
mkdir /path/to/your/workspace/sam-sample # 作業用フォルダを作成
code -r /path/to/your/workspace/sam-sample # 作業用フォルダをVSCodeで開く
```

これでVSCodeが開くので、続いて`Ctrl + Shift + p`でコマンドパレットを開き、開発コンテナのテンプレートを作成します。

```
>Remote-Containers:Add Development Container Configuration Files...
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276566/e934e4a2-13a8-5b6f-0f6e-1b7ce7d10401.png)
その中から`Python 3`を選びます。
※出てこない人は`Show ALL Definetions...`を選んで下さい。`Python 3`が出てくるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276566/841f95e8-cfd1-249b-4fe1-10544b9d86f7.png)
すると開発コンテナ用のテンプレートがフォルダ内に作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276566/755f349f-df84-9ba0-d741-d99e0967cd17.png)
AWS SAM CLIはDockerを利用するのでホストのdocker.sockをマウントします。
`.devcontainer.json`の`name`や`build`と同じ階層にこの行を追加してください。

```json
"mounts": ["source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"],
```
定義した環境を開きます。
`Ctrl + Shift + p`でコマンドパレットを開き、定義した環境を開きます。

```
>Remote-Containers:Reopen in Container
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276566/03b32cc7-6731-6e45-e6dc-17cefa2af052.png)

### AWS SAM CLIのインストール
```bash
root@***:/workspaces/sam-sample# pip3 install aws-sam-cli
root@***:/workspaces/sam-sample# sam --version
SAM CLI, version 1.7.0
```

### プロジェクト作成
`sam init`コマンドでプロジェクトを初期化します。

```bash
root@***:/workspaces/sam-sample# sam init
Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Which runtime would you like to use?
        1 - nodejs12.x
        2 - python3.8
        3 - ruby2.7
        4 - go1.x
        5 - java11
        6 - dotnetcore3.1
        7 - nodejs10.x
        8 - python3.7
        9 - python3.6
        10 - python2.7
        11 - ruby2.5
        12 - java8.al2
        13 - java8
        14 - dotnetcore2.1
Runtime: 2

Project name [sam-app]: 

Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git

AWS quick start application templates:
        1 - Hello World Example
        2 - EventBridge Hello World
        3 - EventBridge App from scratch (100+ Event Schemas)
        4 - Step Functions Sample App (Stock Trader)
        5 - Elastic File System Sample App
Template selection: 1

-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.8
Dependency Manager: pip
Application Template: hello-world
Output Directory: .

Next steps can be found in the README file at ./sam-app/README.md
```
Hello World用のテンプレートが出来上がります。
この状態ではまだ以前の`RestAPI`を使用する構成になっているので少しだけ修正します。
とは言っても`Type: Api`なっている部分を`Type: HttpApi`に切り替えるだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276566/ddfd8afd-394d-a50b-11f4-7f0e32b05c90.png)

### 実行
`sam local start-api`で実行します。

```bash
root@***:/workspaces/sam-sample# cd sam-app/
root@***:/workspaces/sam-sample/sam-app# sam local start-api -v /path/to/your/workspace/sam-sample/sam-app
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-10-30 06:25:31  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
```
先ほど`Type: HttpApi`に切り替えた`/hello`のLambda関数が認識されている事が分かります。

```
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
```

ブラウザでアクセスすると正しく`hello world`が表示され、`HttApi`のサポートが確認出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276566/bbed35a9-7a66-3af6-405b-5c144a5771cf.png)

ちなみに`sam local start-api`時に付けた`-v`オプションは今回重要で、AWS SAM CLIをDocker内で実行する場合はホスト上のプロジェクトのパスを指定してあげる必要があるので気を付けてください。

```bash
sam local start-api --help
...
  -v, --docker-volume-basedir TEXT
                                  Specifies the location basedir where the SAM
                                  file exists. If the Docker is running on a
                                  remote machine, you must mount the path
                                  where the SAM file exists on the docker
                                  machine and modify this value to match the
                                  remote machine.
```

### 以前のバージョンで試してみる
```
root@***:/workspaces/sam-sample/sam-app# pip3 install aws-sam-cli==1.6.2
root@***:/workspaces/sam-sample/sam-app# sam --version
SAM CLI, version 1.6.2
root@***:/workspaces/sam-sample/sam-app# sam local start-api -v /path/to/your/workspace/sam-sample/sam-app
Error: Template does not have any APIs connected to Lambda functions
```
以前のバージョンではそもそもAPIとして認識されませんでした。

# 余談
今回お伝えしたAWS SAM CLIのHttpApiサポートですが、[この機能のPR](https://github.com/aws/aws-sam-cli/pull/1942)に貢献させて頂きました。
元々開かれていたPRに対して不足している機能をPRしただけですが、実は初めてのOSS活動だったのでとても緊張しました。。。
また、OSSという不特定の人間がコミットするリポジトリ管理のやり方も学べたのでOSS活動は重要だと認識出来ました。
OSS活動をされた事がない方も臆さず挑戦する事をお勧めします。